Getting started
Now that you're convinced Civet is right for your current/next project, here is how to set up your environment to get productive right away and have a Good Time℠. Cue the music! 🎧
Quick start
Try out the transpiler interactively in the Playground.
Or transpile Civet code interactively in the command-line REPL:
npx @danielx/civet -cnpx @danielx/civet -cOr run Civet code directly in the command-line REPL:
npx @danielx/civetnpx @danielx/civetInstallation
To install Civet package as a dev dependency in your project:
npm i -D @danielx/civetnpm i -D @danielx/civetFor command-line usage outside package.json scripts, it is also helpful to install Civet globally, which enables a civet command-line interface:
npm i -g @danielx/civetnpm i -g @danielx/civetThe instructions below assume such a global install; if you do not want to, use npx @danielx/civet in place of civet.
If you use VSCode, install the Civet VSCode extension. You will get best results if you also disable the built-in TypeScript extension.
To use TypeScript for type checking (which the VSCode plugin does automatically), create a tsconfig.json file. For example:
{
"compilerOptions": {
"strict": true,
"jsx": "preserve",
"lib": ["es2021"],
"moduleResolution": "bundler",
"forceConsistentCasingInFileNames": true,
"resolveJsonModule": true,
"esModuleInterop": true
},
"ts-node": {
"transpileOnly": true,
"compilerOptions": {
"module": "nodenext"
}
}
}{
"compilerOptions": {
"strict": true,
"jsx": "preserve",
"lib": ["es2021"],
"moduleResolution": "bundler",
"forceConsistentCasingInFileNames": true,
"resolveJsonModule": true,
"esModuleInterop": true
},
"ts-node": {
"transpileOnly": true,
"compilerOptions": {
"module": "nodenext"
}
}
}If you do not set strict: true, we recommend at least setting noImplicitAny: true; otherwise, Civet's generated code sometimes introduces unexpected any types.
Executing code
Simple execution of a .civet source file (CommonJS or ESM):
civet source.civet ...args...civet source.civet ...args...Directly execute a .civet CommonJS or ESM source file in Node:
node --import @danielx/civet/register source.civet ...args...node --import @danielx/civet/register source.civet ...args...On Node <20.6.0, you also need to specify --loader @danielx/civet/esm for ESM import of .civet files.
The registration scripts and CLI will automatically search for Civet configuration files in the source file's directory and ancestor directories. To disable this behavior, use one of the following:
civet --no-config source.civet ...args...
node --import @danielx/civet/register-noconfig source.civet ...args...civet --no-config source.civet ...args...
node --import @danielx/civet/register-noconfig source.civet ...args...Transpilation
Simple compilation of one .civet source file to TypeScript:
npx @danielx/civet < source.civet > output.tsnpx @danielx/civet < source.civet > output.tsCompile several .civet source files to .civet.tsx (default extension):
civet -c *.civetcivet -c *.civetCompile several .civet source files to .js:
civet --js -c *.civet -o .jscivet --js -c *.civet -o .jsTo see all command-line options:
civet --helpcivet --helpTo transpile within an ESM NodeJS app (assuming npm i -D @danielx/civet):
import {compile} from "@danielx/civet"
const tsCode = await compile(civetCode)
const tsCodeWithSourceMap = await compile(civetCode, {inlineMap: true})
const jsCode = await compile(civetCode, {js: true})import {compile} from "@danielx/civet"
const tsCode = await compile(civetCode)
const tsCodeWithSourceMap = await compile(civetCode, {inlineMap: true})
const jsCode = await compile(civetCode, {js: true})To transpile within a CommonJS NodeJS app (assuming npm i -D @danielx/civet):
{compile} = require("@danielx/civet")
// rest as above{compile} = require("@danielx/civet")
// rest as aboveIf you need compilation to be synchronous, pass in the sync: true option. This will disable certain features with comptime.
To transpile in the browser, you can load the browser build dist/browser.js via a <script> tag, and access the global variable Civet, as in Civet.compile. Alternatively, if you're using a build system, you can import "@danielx/civet" normally, but you'll need to mark "fs" as an external dependency (see e.g. esbuild instructions and Vite instructions).
See the API types for more details about the Civet API.
Typechecking
You can ask Civet to run TypeScript to check for type errors in your Civet code (the analog of tsc):
civet --typecheckcivet --typecheckThis command returns an error code if there are any type errors, so you can use it in an NPM script and in CI.
Alternatively, you can typecheck just specific files:
civet --typecheck new.civetcivet --typecheck new.civetYou can typecheck and generate JavaScript/TypeScript files at the same time. This could be a good NPM build script, for example. Note that JavaScript/TypeScript files will be generated even if there are type errors.
civet -c --typecheck src/**/*.civetcivet -c --typecheck src/**/*.civetYou can also use TypeScript to generate .d.ts declaration files (if there are no type errors):
civet --emit-declaration
civet --emit-declaration src/**/*.civetcivet --emit-declaration
civet --emit-declaration src/**/*.civetBuilding a project
Use Civet's built-in unplugin to integrate with many bundlers: Vite, esbuild, Astro, Farm, Rolldown, Rollup, Webpack. For example:
import esbuild from 'esbuild'
import civetPlugin from '@danielx/civet/esbuild'
esbuild.build({
// ...
// sourcemap: true, // build and link sourcemap files
plugins: [
civetPlugin({
// Options and their defaults:
// emitDeclaration: false, // generate .d.ts files?
// declarationExtension: '.civet.d.ts', // extension for .d.ts files
// implicitExtension: true, // import "./x" checks for x.civet
// outputExtension: '.tsx', // appended to .civet internally
// ts: 'civet', // TS -> JS transpilation mode
// typecheck: false, // check types via tsc
// cache: true, // cache compilation results based on mtime, useful for watch
// config: null, // Civet config filename; null to skip
// parseOptions: { // directives to apply globally
// comptime: false, // evaluate comptime blocks
// },
})
]
}).catch(() => process.exit(1))import esbuild from 'esbuild'
import civetPlugin from '@danielx/civet/esbuild'
esbuild.build({
// ...
// sourcemap: true, // build and link sourcemap files
plugins: [
civetPlugin({
// Options and their defaults:
// emitDeclaration: false, // generate .d.ts files?
// declarationExtension: '.civet.d.ts', // extension for .d.ts files
// implicitExtension: true, // import "./x" checks for x.civet
// outputExtension: '.tsx', // appended to .civet internally
// ts: 'civet', // TS -> JS transpilation mode
// typecheck: false, // check types via tsc
// cache: true, // cache compilation results based on mtime, useful for watch
// config: null, // Civet config filename; null to skip
// parseOptions: { // directives to apply globally
// comptime: false, // evaluate comptime blocks
// },
})
]
}).catch(() => process.exit(1))INFO
You can mix and match .civet files with .js and .ts files. Even .coffee will work if you require coffeescript/register or add a loader for it.
See the unplugin documentation for more configurations, including full working examples.
These plugins should support metaframeworks built upon these bundlers. For example, the esbuild unplugin supports tsup:
// tsup.config.ts
import { defineConfig } from 'tsup';
import civetPlugin from '@danielx/civet/esbuild';
export default defineConfig({
entryPoints: ['main.civet'],
esbuildPlugins: [
civetPlugin({
// options
}),
],
});// tsup.config.ts
import { defineConfig } from 'tsup';
import civetPlugin from '@danielx/civet/esbuild';
export default defineConfig({
entryPoints: ['main.civet'],
esbuildPlugins: [
civetPlugin({
// options
}),
],
});If you want to use other bundlers, check out our integrations page for a suitable plugin.
Civet