Environment
With each execution, jko creates an Independent environment—an entirely new instance that derives from either the system environment or the parent process environment.
The environment variables can be reached in various contexts:
- Function scripts:
process.env.NAME - Traditional scripts:
$NAME - Other processes: through mechanisms specific to each process (e.g., a Node.js process uses
process.env.NAME)
For example:
export default {
scripts: {
functionScriptA: function (param1, param2) {
console.log('functionScriptA')
process.env.jko_return_0 = `1. ${param1}_${param2}`
return 'functionScriptB'
},
functionScriptB: function (param1, param2) {
console.log('functionScriptB')
process.env.jko_return_1 = `2. ${param1}_${param2}`
return 'scriptC'
},
scriptC: 'echo scriptC: $jko_arg_0, $jko_return_0, $jko_return_1',
scriptD: 'jko functionScriptA 2 3 && jko scriptC'
}
}
(Actually, the output will be longer, but it has been simplified to emphasize functionality over presentation. To get the exact same output as in the example, must add -l=e options to all jko executions)
When executed:
$ jko scriptD
$ functionScriptA
$ functionScriptB
$ scriptC: 2, 1. 2_3, 2. 2_3
$ scriptC: , ,
scriptD chains two processes: jko functionScriptA 2 3 and jko scriptC.
Each execution creates an "Independent" environment:
- In the first execution, being a chaining, the environment is shared, so when the tail script is invoked, it receives all the values. That's why you see
scriptC: 2, 1. 2_3, 2. 2_3. - In the second execution, which operates in an "Independent" environment, both
jko_return_0andjko_return_1are empty. As a result, the output isscriptC: , ,.

Let's change a few lines in functionScriptA and scriptD:
export default {
scripts: {
functionScriptA: function (param1, param2) {
console.log('functionScriptA')
process.env.jko_return_0 = `1. ${param1}_${param2}`
return 'scriptD'
},
functionScriptB: function (param1, param2) {
console.log('functionScriptB')
process.env.jko_return_1 = `2. ${param1}_${param2}`
return 'scriptC'
},
scriptC: 'echo scriptC: $jko_arg_0, $jko_return_0, $jko_return_1',
scriptD: 'jko functionScriptB && jko scriptC',
}
}
(Actually, the output will be longer, but it has been simplified to emphasize functionality over presentation. To get the exact same output as in the example, must add -l=e options to all jko executions)
When executed:
$ jko functionScriptA 2 3
$ functionScriptA
$ functionScriptB
$ scriptC: 2, 1. 2_3, 2. undefined_undefined
$ scriptC: 2, 1. 2_3,
-
Shared Environment Creation:
Executing
jko functionScriptA 2 3creates a Shared environment used by the two chained processesjko functionScriptBandjko scriptC, and also by their descendants.- In this process,
jko_return_0becomes available to both. - However, both
jko functionScriptBandjko scriptCoperate within their own Independent environments.
- In this process,
-
Argument Availability:
Although the arguments
2and3are available inscriptD, they are not accessible tofunctionScriptB. This is why the output displaysundefinedfor those values (scriptC: 2, 1. 2_3, 2. undefined_undefined).- Nevertheless,
jko_arg_0andjko_arg_1belong to the Shared environment and remain available.
- Nevertheless,
-
Additionally,
jko_return_1is defined in thefunctionScriptBIndependent environment and is not accessible to the initialscriptC. This is why the output appears as:scriptC: 2, 1. 2_3,.

Let's change a line in functionScriptB:
export default {
scripts: {
functionScriptA: function (param1, param2) {
console.log('functionScriptA')
process.env.jko_return_0 = `1. ${param1}_${param2}`
return 'scriptD'
},
functionScriptB: function () {
console.log('functionScriptB')
process.env.jko_return_1 = `2. ${process.env.jko_arg_0}_${process.env.jko_arg_1}`
return 'scriptC'
},
scriptC: 'echo scriptC: $jko_arg_0, $jko_return_0, $jko_return_1',
scriptD: 'jko functionScriptB && jko scriptC',
}
}
(Actually, the output will be longer, but it has been simplified to emphasize functionality over presentation. To get the exact same output as in the example, must add -l=e options to all jko executions)
When executed:
$ jko functionScriptA 2 3
$ functionScriptA
$ functionScriptB
$ scriptC: 2, 1. 2_3, 2. 2_3
$ scriptC: 2, 1. 2_3,
Using jko_arg_0 and jko_arg_1, which belong to the Shared environment, allows functionScriptB to access to original arguments.
Shared Environments
Chained processes share a common environment. As a result:
- The environment variables holding the initial arguments are accessible in every script.
- Newly added environment variables are available to subsequent scripts after their definition.
Review the following image that demonstrates how the environment evolves during the chaining calls:

See that:
- Initial arguments,
jko_arg_0,jko_arg_1, etc. are accessible in every script,functionScript1,functionScript2andfunctionScript3.- Furthermore, they can be accessed as parameters these functions.
jko_return_0is accessible tofunctionScript2andfunctionScript3.jko_return_1is accessible tofunctionScript3.
For example:
export default {
scripts: {
functionScript1: function (param1, param2) {
console.log('functionScript1:')
console.log(param1 === process.env.jko_arg_0)
console.log(param2 === process.env.jko_arg_1)
process.env.jko_return_0 = `1. ${process.env.jko_arg_0}_${process.env.jko_arg_1}`
return 'functionScript2'
},
functionScript2: function (param1, param2) {
console.log('functionScript2:')
console.log(param1 === process.env.jko_arg_0)
console.log(param2 === process.env.jko_arg_1)
console.log(process.env.jko_return_0 === `1. ${process.env.jko_arg_0}_${process.env.jko_arg_1}`)
process.env.jko_return_1 = `2. ${process.env.jko_arg_0}_${process.env.jko_arg_1}`
return 'functionScript3'
},
functionScript3: function (param1, param2) {
console.log('functionScript3:')
console.log(param1 === process.env.jko_arg_0)
console.log(param2 === process.env.jko_arg_1)
console.log(process.env.jko_return_0 === `1. ${process.env.jko_arg_0}_${process.env.jko_arg_1}`)
console.log(process.env.jko_return_1 === `2. ${process.env.jko_arg_0}_${process.env.jko_arg_1}`)
// End of the chaining
}
}
}
When executed:
$ jko functionScript1 1 2
$ functionScript1:
$ true
$ true
$ functionScript2:
$ true
$ true
$ true
$ functionScript3:
$ true
$ true
$ true
$ true
$ jko functionScript2 1 2
$ functionScript2:
$ true
$ true
$ false
$ functionScript3:
$ true
$ true
$ false
$ true
(Actually, the output will be longer, but it has been simplified to emphasize functionality over presentation. To get the exact same output as in the example, use the following command: jko -l=e functionScript1 1 2)
Enhancing Environment
Use envFile in jko.js to specify the path of a .env file, which provides required environment variables
to the new instance where the script will run.
jko.js:
export default {
scripts: {
yourScript1: "someCommand",
},
envFile: './path/to/.env',
}
.env:
SOME_ENV_VAR=VALUE1
Additionally, the .env file can be specified using the CLI option --env-file:
$ jko --env-file=./path/to/.env yourScript arg1 ... argN
command line option --env-file takes precedence over envFile.
Additional Environment Variables
In addition to generating environment variables for each command-line argument,
jko creates environment variables for every field exported by jko.js (package.json,
or any configuration file specified via the --config-file option) — excluding scripts field.
These environment variables are generated with a jko_ prefix. Additionally, for compatibility reasons, variables prefixed with npm_package_ are also added.
For example, using the following jko.js:
export default {
scripts: {
yourScript1: "someCommand",
},
envFile: './path/to/.env',
dependencies: {
packageName1: "1.0.0"
},
devDependencies: {
devPackageName1: "1.0.0"
},
packageManager: 'yarn',
logLevel: 'warn',
config: {
data: ['A', 'B']
},
version: '1.2.3',
name: 'theName'
}
jko will generated the following variables:
jko_config_data_0,npm_package_config_data_0.jko_config_data_1,npm_package_config_data_1.jko_version,npm_package_version.jko_name,npm_package_name.- etc.
You can provide default jko_arg_ values using this mechanism—simply define an arg field as an array:
export default {
scripts: {
yourScript1: "someCommand",
},
arg: ['arg1', 'argN']
}
Summary
- Each
jkoexecution runs in a new Independent Environment. This environment may belong to a Shared Environment or not, and it is a Shared Environment among its descendant processes. - Chained function scripts run in a Shared Environment.
- Chained commands in traditional scripts run in a Shared Environment.
jkointroduces custom environment variables with ajko_prefix (and, for compatibility, supports variables prefixed withnpm_package_).- Environment variables will be reachable in multiple ways. For function scripts, use
process.env.NAME; for traditional scripts, use$NAME; and for other processes, the access method varies.