Template variables are placeholder tokens in your .surql schema files that SurrealKit substitutes with actual values at runtime. A single set of schema files can then cover all environments (development, staging, production) with names, prefixes, or other values varying per environment.
Syntax
Use ${VAR_NAME} anywhere in a .surql file:
-- database/schema/roles.surql
DEFINE ROLE ${talent_role} PERMISSIONS FULL;
-- database/schema/tables.surql
DEFINE TABLE ${schema_prefix}_orders SCHEMAFULL;
DEFINE FIELD owner ON ${schema_prefix}_orders TYPE record<user>;Variable names are case-insensitive: ${FOO}, ${foo}, and ${Foo} all match the key FOO.
If a variable is referenced in a file but has no value configured, SurrealKit exits with an error and a clear message indicating which variable is missing.
Resolution order
SurrealKit resolves variable values in the following order (first match wins):
CLI flag:
--var KEY=VALUE(repeatable)**Environment variable:** `SURREALKIT_VAR_` (case-insensitive key matching)
surrealkit.toml[variables]section
CLI flags
surrealkit sync --var schema_prefix=acme --var talent_role=talent_rw
surrealkit rollout start my_rollout --var schema_prefix=acmeEnvironment variables
export SURREALKIT_VAR_SCHEMA_PREFIX=acme
export SURREALKIT_VAR_TALENT_ROLE=talent_rw
surrealkit sync --user root --pass secret surrealkit.toml
[variables]
schema_prefix = "myapp"
talent_role = "talent_rw"
environment = "development"Place surrealkit.toml in the root of your project. It is read automatically. The same file also holds the [typegen] section when TypeScript generation is enabled.
Escaping
To emit a literal ${...} string in generated SQL (for example, inside a SurrealQL string value), double the dollar sign:
SET note = 'pass $${MY_VAR} literally';SurrealKit outputs this as pass ${MY_VAR} literally without substitution.
Which commands apply substitution
Template Variables are substituted when applying schema to a database. They are not substituted in commands that only read or plan:
| Command | Substitution applied |
|---|---|
sync | Yes |
seed | Yes |
rollout start | Yes |
rollout complete | Yes |
rollout rollback | Yes |
rollout plan | No |
rollout baseline | No |
rollout status | No |
rollout lint | No |
Known limitations
Hash-based re-sync: SurrealKit tracks files by content hash. Changing a variable value without editing the file will not trigger a re-sync. Touch the file to force re-application:
touch database/schema/tables.surql
surrealkit sync --user root --pass secretWatch mode: Variables in surrealkit.toml are resolved once at startup. If you edit surrealkit.toml while --watch is running, restart SurrealKit for the new values to take effect. Variables passed via --var or environment variables are re-read on each sync cycle.
Catalog snapshots: Entity names containing ${VAR} appear literally (without substitution) in catalog_snapshot.json. This is cosmetic and does not affect functionality.
String literals: Substitution is purely textual. ${VAR} inside a SurrealQL string is replaced with the variable's value, which may or may not be the intended behaviour. Test carefully when embedding variables inside string literals.