Skip to content

Config

Civet offers many configuration options to adjust the language to your liking. We start with the various options, and then show the various ways that they can be specified.

General Options

ConfigurationWhat it enables
tab=Ntreat tab like N spaces (default=1)

Import Options

TypeScript only allows importing .ts files as .js; see this issue. As a workaround, Civet automatically rewrites imports to .ts into imports to .js. Some environments, such as Deno, allow importing .ts directly, and following ESM, require importing files with the correct extension.

ConfigurationWhat it enables
rewrite-civet-imports=.extRewrite import "file.civet" to import "file.ext"
-rewrite-ts-importsdisable rewriting .ts.js in imports to avoid this issue (useful in environments supporting direct imports of .ts)

Language Options

ConfigurationWhat it enables
autoConstautomatically declare undeclared variables with const
autoLetautomatically declare undeclared variables with let
autoVarautomatically declare undeclared variables with var
defaultElement=tagspecify default JSX tag: <.foo><tag class="foo">
globals=foo,baravoid automatically declaring listed global variables
iifewrap the program in an IIFE to shield globals
jsxCodetreat all JSX children as Civet code
jsxCodeNestedtreat indented JSX children as Civet code
jsxCodeSameLinetreat same-line JSX children as Civet code
objectIsimplement the is operator via Object.is
replwrap the program in an IIFE that exposes globals
strictenable JavaScript strict mode (equivalent to "use strict")

ECMAScript Compatibility

Eventually, we plan a jsCompat compatibility flag to modify Civet to be closer to pure ECMAScript, removing the few places where Civet is not a superset of ECMAScript. For now, we have the following related options:

ConfigurationWhat it enables
-implicit-returnsturn off implicit return of last value in functions

CoffeeScript Compatibility

ConfigurationWhat it enables
coffeeCompatenable all of the following CoffeeScript compatibility flags
autoVarautomatically declare undeclared variables with var
coffeeBinaryExistentialx ? yx ?? y
coffeeBooleansyes, no, on, off
coffeeClassesCoffeeScript-style class methods via -> functions
coffeeComment# single line comments
coffeeDivx // y integer division instead of JS comment
coffeeDodo ->; disables ES6 do...while loops and Civet do blocks
coffeeEq=====, !=!==
coffeeForLoopsfor in/of/from loops behave like they do in CoffeeScript (like Civet's for each of/in/of respectively)
coffeeInterpolation"a string with #{myVar}", ///regex #{myVar}///
coffeeIsntisnt!==
coffeeJSXJSX children ignore indentation; tags need to be explicitly closed
coffeeLineContinuation\ at end of line continues to next line
coffeeNotnot!, disabling Civet extensions like is not
coffeeOfa of ba in b, a not of b!(a in b), a in bb.indexOf(a) >= 0, a not in bb.indexOf(a) < 0
coffeePrototypex:: -> x.prototype, x::y -> x.prototype.y
coffeeRange[a..b] increases or decreases depending on whether a < b or a > b

Environment Options

Running in a particular environment? Try one of these options:

ConfigurationWhat it enables
clientCode may run on client (default unless you specify server, currently just for Solid)
deno-rewrite-ts-imports
reactUse className instead of class in JSX class shorthand
serverCode may run on server (currently just for Solid)
solidAutomatic type casting of JSX

Local Configuration via Directives

At the top of any Civet file (possibly after a #! line, comments, triple slash directives, and other string directives such as "use strict"), you can specify one or more configurations with a "civet" directive. For example:

js
"civet objectIs -implicit-returns tab=2"
"civet objectIs -implicit-returns tab=2"

This directive specifies that:

In general, a word like objectIs or object-is enables a feature; a negated word like -implicitReturns or -implicit-returns disables a feature; and an assignment like tab=2 specifies a value for a feature (in rare cases). You can use camelCase or kebab-case as you prefer.

Global Configuration via Config Files

In the root directory of your project, or in a .config subdirectory, you can add one of the following files:

  • 🐈.json
  • civetconfig.json
  • civet.config.json
  • package.json with a "civetConfig" property
  • Any of the above with .yaml or .yml extension
  • Any of the above with a .civet or .js extension, with code that export defaults an object equivalent to a JSON file.

The JSON data should consist of an object with a "parseOptions" property, which should be an object specifying one of more directives in the natural way. For example, the directive"civet objectIs -implicit-returns tab=2" is equivalent to:

js
{
  "parseOptions": {
    "objectIs": true,
    "implicitReturns": false,
    "tab": 2
  }
}
{
  "parseOptions": {
    "objectIs": true,
    "implicitReturns": false,
    "tab": 2
  }
}

Global Configuration within Build Tools

The unplugin offers options to specify global config directives (overriding even config files) and to specify or disable a config file. For example:

js
civetPlugin({
  parseOptions: {
    objectIs: true,
    implicitReturns: false,
    tab: 2,
  },
})
civetPlugin({
  parseOptions: {
    objectIs: true,
    implicitReturns: false,
    tab: 2,
  },
})

Configuration via API

The Civet compilation API (compile) offers a similar parseOptions for specifying config directives:

js
import {compile} from "@danielx/civet"
const code = await compile(civetCode, {
  parseOptions: {
    objectIs: true,
    implicitReturns: false,
    tab: 2,
  },
})
import {compile} from "@danielx/civet"
const code = await compile(civetCode, {
  parseOptions: {
    objectIs: true,
    implicitReturns: false,
    tab: 2,
  },
})

compile does not look at config files. Instead, you can use the config module to look for and parse config files:

js
import { findInDir, findConfig, loadConfig } from "@danielx/civet/config"
// Look for standard name for config file in specified directory
const path1 = await findInDir(process.cwd())
// Look for standard name for config file in specified directory or ancestors
const path2 = await findConfig(process.cwd())
// Load config file from specified path
const config = await loadConfig(path)
// Pass config to compile
const code = await compile(civetCode, config)
import { findInDir, findConfig, loadConfig } from "@danielx/civet/config"
// Look for standard name for config file in specified directory
const path1 = await findInDir(process.cwd())
// Look for standard name for config file in specified directory or ancestors
const path2 = await findConfig(process.cwd())
// Load config file from specified path
const config = await loadConfig(path)
// Pass config to compile
const code = await compile(civetCode, config)

Configuration via CLI

By default, the Civet CLI searches all ancestor directories of the current directory for a configuration file with a standard name. It also options to specify config directives and to override config files:

sh
# Specify a directive
civet --civet "objectIs -implicit-returns tab=2" ...
# Specify a config file
civet --config custom-config.civet ...
# Disable config files
civet --no-config ...
# Specify a directive
civet --civet "objectIs -implicit-returns tab=2" ...
# Specify a config file
civet --config custom-config.civet ...
# Disable config files
civet --no-config ...

Compiler Options

In addition to the "parse options" described above, there are a few top-level options (above parseOptions):

  • threads: Use specified number of Node worker threads to compile Civet files faster. Default: 0 (don't use threads), or CIVET_THREADS environment variable if set.