keycloak-runner
v0.0.1-alpha.3
Published
Download a Keycloak release from GitHub, optionally add providers and realm imports, and run `start-dev`. You can also **patch any realm** using [`@keycloak/keycloak-admin-client`](https://www.npmjs.com/package/@keycloak/keycloak-admin-client): the runner
Readme
keycloak-runner
Download a Keycloak release from GitHub, optionally add providers and realm imports, and run start-dev. You can also patch any realm using @keycloak/keycloak-admin-client: the runner shallow-merges your JSON into the current realm representation, then updates via the Admin API.
Install
bun installRun (development)
bun run index.tsRealm import files for start-dev use -r / --realm-import. The --realm name on the default command is only for post-start Admin API patches (together with --patch or --patch-file); the patch-realm subcommand also uses --realm for the same meaning.
bun run index.ts -r ./my-realm-export.jsonOn first start (no master realm yet), Keycloak creates a temporary admin user from KC_BOOTSTRAP_ADMIN_USERNAME / KC_BOOTSTRAP_ADMIN_PASSWORD and from --bootstrap-admin-username / --bootstrap-admin-password (injected right after start-dev unless you pass your own). Defaults are admin / admin, or use KEYCLOAK_ADMIN_USER / KEYCLOAK_ADMIN_PASSWORD. That user is what patch-realm and admin-cli use.
If you previously started Keycloak without a bootstrap admin and only saw the browser welcome wizard, the realm may already exist without that user—start once with -c / --clean to wipe the cached install and get a fresh bootstrap, or finish creating an admin in the UI and align env credentials with it.
Importing a realm JSON (-r / --realm-import) on the very first start can sometimes create master before bootstrap runs; if you see the welcome screen anyway, create the admin in the UI once or avoid importing a full master export on first boot.
patch-realm
Shallow-merge a JSON object into an existing realm: only top-level keys from your patch are written onto the realm returned by the Admin API. Nested objects in the patch replace the entire existing value for that key. The patch root must be a JSON object (not an array or primitive).
Realm fetch and update use @keycloak/keycloak-admin-client (realms.findOne / realms.update). Authentication uses the password grant with the admin-cli client (token realm master, same admin user as bootstrap). That may be disabled in hardened setups; it is aimed at local start-dev workflows.
Environment variables
| Variable | Default | Purpose |
|----------|---------|---------|
| KEYCLOAK_ADMIN_USER | admin | Admin API username |
| KEYCLOAK_ADMIN_PASSWORD | admin | Admin API password |
Options
| Option | Description |
|--------|-------------|
| --realm <name> | Required. Realm to patch. |
| --keycloak-url <url> | Base URL, no trailing slash (default: http://127.0.0.1:8080). Must match Keycloak’s HTTP URL (host and port). |
| --ready-timeout <ms> | How long to wait for readiness (default: 120000). |
| --patch '<json>' | Inline JSON object. Mutually exclusive with --patch-file. |
| --patch-file <path> | Read patch from a file. Use - to read JSON from stdin. Mutually exclusive with --patch. |
You must supply exactly one of --patch or --patch-file.
Examples
Inline JSON
bun run index.ts patch-realm --realm master --patch '{"adminTheme":"keycloak.v2"}'Patch file
bun run index.ts patch-realm --realm myrealm --patch-file ./patch.jsonStdin (--patch-file -)
echo '{"loginTheme":"keycloak.v2"}' | bun run index.ts patch-realm --realm master --patch-file -One command: provider + start-dev + patch
After the server process is spawned, the runner waits for Keycloak, then applies the same merge as patch-realm. The patch is loaded before start-dev starts (so --patch-file - can read patch JSON from stdin without the server consuming it).
| -p, --provider <jar...> | Provider JAR(s) copied into providers/ before start-dev. |
| -t, --theme <name>:<path> | Symlink an exploded theme directory into themes/<name>/ (repeatable). <path> must contain a login/ subdirectory. |
Put runner flags before --; anything after -- is passed to Keycloak.
Theme development (filesystem + cache disabled)
Symlink a theme from your project and disable theme caching for live edits:
keycloak-runner \
-p ../login-ui-base/target/keycloak-login-ui-base-1.0.0-SNAPSHOT.jar \
-t acme-login:../acme-login/src/main/resources/theme/acme-login \
--realm master \
--patch '{"loginTheme":"acme-login"}' \
-- \
--spi-theme-static-max-age=-1 \
--spi-theme-cache-themes=false \
--spi-theme-cache-templates=falseUse valid JSON (double-quoted keys and strings). The value of adminTheme must match the theme name your JAR registers (check the theme’s theme.properties).
If you change the HTTP port:
keycloak-runner --keycloak-url http://127.0.0.1:9000 \
-p path/to/theme.jar \
--realm master \
--patch '{"adminTheme":"onboarding-ui"}' \
-- --http-port 9000Two terminals (alternative)
# Terminal 1
bun run index.ts -p ../onboarding-ui/target/keycloak-onboarding-ui-theme.jar
# Terminal 2 (after server is ready)
bun run index.ts patch-realm --realm master --patch '{"adminTheme":"onboarding-ui"}'Build the CLI binary
bun run prepareThe keycloak-runner bin points at dist/keycloak-runner.js.
This project was created using bun init in bun v1.3.13. Bun is a fast all-in-one JavaScript runtime.
