Skip to content

Stack & Forbidden Constructs

Specification > Engineering

This chapter fixes the runtime, module system, and project layout for JavaScript code, and names the language constructs you must not use. It is conditional: it applies to source files written as ES modules (**/*.mjs) and does not constrain other ecosystems.


AspectRule
RuntimeYou MUST target Node.js 22 and MAY use its current syntax.
Module systemYou MUST write ES modules; source files MUST use the .mjs extension.
ImportsYou MUST use import / export; you MUST NOT use CommonJS require.

You MUST place application modules under ./src/. Runtime configuration MUST live in a single module at ./src/data/config.mjs, so that settings have one well-known location instead of being scattered across the tree.

./src/
./src/data/config.mjs
...feature modules

The following constructs are prohibited. Each row states the rule and the sanctioned alternative.

ConstructRuleUse instead
for / while loopsMUST NOTarray methods (map, filter, reduce, forEach)
process.argvMUST NOTa dedicated configuration module
fs for risky operationsMUST NOTguarded, purpose-built helpers
eval()MUST NOTexplicit parsing or a lookup table
.then().catch() chainsSHOULD NOTasync / await

Iteration MUST be expressed with array methods rather than imperative loops:

// Prohibited
for( let i = 0; i < items.length; i++ ) {
total += items[ i ].price
}
// Required
const total = items.reduce( ( sum, item ) => sum + item.price, 0 )

You SHOULD express asynchronous work with async / await rather than promise continuation chains, because linear control flow is easier to read and to trace:

// Discouraged
const load = () => fetchUser().then( ( user ) => render( user ) ).catch( handle )
// Preferred
const load = async () => {
const user = await fetchUser()
return render( user )
}