Civet
The Modern Way to Write TypeScript
Expressive Syntax and Faster Coding with Civet

Civet is a programming language that compiles to TypeScript or JavaScript, so you can use existing tooling but enable concise and powerful syntax. In addition to 99% JS/TS compatibility, there are many features, with some highlights below and more comprehensive examples in the reference. See also Civet's design philosophy.
Highlights: Beyond TC39
Civet code on the lefttop, compiled TypeScript output on the rightbottom.
Pattern Matching
TC39 Proposal: Pattern Matching
switch x
0
console.log("zero")
/^\s+$/
console.log("whitespace")
[{type: "text", content}, ...rest]
console.log("leading text", content)
Edit inline or edit in the Playground!
if (x === 0) {
console.log("zero");
} else if (
typeof x === "string" &&
/^\s+$/.test(x)
) {
console.log("whitespace");
} else if (
Array.isArray(x) &&
x.length >= 1 &&
typeof x[0] === "object" &&
x[0] != null &&
"type" in x[0] &&
x[0].type === "text" &&
"content" in x[0]
) {
const [{ type, content }, ...rest] = x;
console.log("leading text", content);
}
Pipelines
data
|> Object.keys
|> console.log
Edit inline or edit in the Playground!
console.log(Object.keys(data));
Pipe expression with shorthand functions:
a |> & + 1 |> bar
Edit inline or edit in the Playground!
bar(a + 1);
Single-Argument Function Shorthand
x.map .name
x.map &.profile?.name[0...3]
x.map &.callback a, b
x.map &+1
x.map -&
Edit inline or edit in the Playground!
x.map(($) => $.name);
x.map(($1) => $1.profile?.name.slice(0, 3));
x.map(($2) => $2.callback(a, b));
x.map(($3) => $3 + 1);
x.map(($4) => -$4);
Custom Infix Operators
operator {min, max} := Math
value min ceiling max floor
Edit inline or edit in the Playground!
const { min, max } = Math;
max(min(value, ceiling), floor);
Declarations in Conditions and Loops
if match := regex.exec string
console.log match
Edit inline or edit in the Playground!
let ref;
if ((ref = regex.exec(string))) {
const match = ref;
console.log(match);
}
Everything is an Expression
items = for item of items
if item.length
item.toUpperCase()
else
"<empty>"
Edit inline or edit in the Playground!
items = (() => {
const results = [];
for (const item of items) {
if (item.length) {
results.push(item.toUpperCase());
} else {
results.push("<empty>");
}
}
return results;
})();
return
if x == null
throw "x is null"
else
log `received x of ${x}`
x.value()
Edit inline or edit in the Playground!
return x == null
? (() => {
throw "x is null";
})()
: (log(`received x of ${x}`), x.value());
x = do
const tmp = f()
tmp * tmp + 1
Edit inline or edit in the Playground!
x = (() => {
{
const tmp = f();
return tmp * tmp + 1;
}
})();
Dedented Strings and Templates
text = """
This text is a string that doesn't include
the leading whitespace.
"""
Edit inline or edit in the Playground!
text = `This text is a string that doesn't include
the leading whitespace.`;
text = ```
Also works for
${templates}!
```
Edit inline or edit in the Playground!
text = `Also works for
${templates}!`;
Chained Comparisons
a < b <= c
a is b is not c
a instanceof b not instanceof c
Edit inline or edit in the Playground!
a < b && b <= c;
a === b && b !== c;
a instanceof b && !(b instanceof c);
Default to const
for Iteration Items
for (item of [1, 2, 3, 4, 5]) {
console.log(item * item);
}
Edit inline or edit in the Playground!
for (const item of [1, 2, 3, 4, 5]) {
console.log(item * item);
}
Spread in Any Position
Spreads in first or middle position:
[...head, last] = [1, 2, 3, 4, 5]
Edit inline or edit in the Playground!
([...head] = [1, 2, 3, 4, 5]),
([last] = head.splice(-1));
{a, ...rest, b} = {a: 7, b: 8, x: 0, y: 1}
Edit inline or edit in the Playground!
({ a, b, ...rest } = { a: 7, b: 8, x: 0, y: 1 });
function justDoIt(a, ...args, cb) {
cb.apply(a, args)
}
Edit inline or edit in the Playground!
function justDoIt(a, ...args) {
let [cb] = args.splice(-1);
return cb.apply(a, args);
}
Import Syntax Matches Destructuring
import {X: LocalX, Y: LocalY} from "./util"
Edit inline or edit in the Playground!
import { X as LocalX, Y as LocalY } from "./util";
Export Convenience
export a, b, c from "./cool.js"
export x = 3
Edit inline or edit in the Playground!
export { a, b, c } from "./cool.js";
export var x = 3;
JSX
function Listing(props)
<h1 #heading>Hello Civet!
<ul .items>
<For each=props.items>
(item) =>
<li .item {props.style}><Item {item}>
Edit inline or edit in the Playground!
function Listing(props) {
return (
<>
<h1 id="heading">Hello Civet!</h1>
<ul class="items">
<For each={props.items}>
{(item) => {
return (
<li
class="item"
style={props.style}
>
<Item item={item} />
</li>
);
}}
</For>
</ul>
</>
);
}
Sponsors
Thank you to all of our sponsors for your invaluable support and contribution to the Civet language!
Contributors
Thank you for your work and dedication to the Civet project!