Civet compiles to TypeScript, so its cleverness has to survive a translation step
A TypeScript superset that favors more types and less typing
At a glance
- What is it?
- Civet is a CoffeeScript-style superset of TypeScript that adds pattern matching, pipes, indentation-based JSX and block shorthand, then emits ordinary TypeScript. Its value is in how much it removes from your source; its cost is that everything you write goes through a compiler you now depend on.
- Who is it for?
- Adopt Civet if your team already writes TypeScript and spends real time on destructuring, object literals and JSX closing tags, because those are exactly what the shorthand removes, and the emitted TypeScript means your types, your bundler and your editor tooling survive unchanged.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 5 days ago.
- What is it written in?
- Mainly C, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 22, 2026, and from our analysis. They are not legal advice.
Editorial analysis
The output is TypeScript, which is the whole design decision
Civet describes itself as a tasteful superset of TypeScript, and its quickstart includes a mode whose entire job is to show you that claim. `civet -c` starts a REPL that transpiles typed Civet code into TypeScript, and `civet < source.civet > output.ts` does the same for a file.
So the contract is not that you run Civet forever. It is that you run it until the output is what you want, and everything downstream continues to work. TypeScript still type-checks the output, your bundler still reads the output, and your editor still understands the output.
The package itself is `@danielx/civet`, described in package.json as CoffeeScript style syntax for TypeScript, currently at version 0.11.16. It is a CommonJS package whose build is a shell script, `bash./build/build.sh`.
The repository is not archived and the last push was on 2026-10-13, so work is current. There are no GitHub releases at all, which is the one maintenance fact that deserves a second look before anyone depends on it.
The CLI covers REPL, one-shot compile, execution and type checking
The quickstart is short enough to take at face value, and each command does something different.
# Install
npm install -g @danielx/civet
# Run Civet code directly in a REPL
civet
# Transpile typed Civet code into TypeScript in a REPL
civet -cFor a single file there is a filter-style invocation, `civet source.civet...args...`, which compiles and runs it with arguments passed through. There is also a Node registration path that does not require the CLI at all:
node --import @danielx/civet/register source.civetThat last one matters more than it looks. It means a `.civet` file can be run by an existing Node workflow without a separate build step, the same way a loader hook works for other extensions.
Type checking is a separate command, and the flag spelling is the sort of detail worth copying exactly:
# Type check entire project, which requires TypeScript installed
npm install -g typescript
civet --typecheckNote the requirement. TypeScript must be installed, because Civet shells out to it rather than bundling a type checker. The `typecheck` script specifies `.cache/typecheck.tsbuildinfo` as its `tsbuildinfo` path.
The proposal features are where the ergonomics win
The feature list is organised by provenance, and the first group is the most valuable: ES features that are new or proposed.
Pattern matching follows the TC39 proposal, and it works in `switch` with destructuring patterns, for example matching `[{type: "text", name}, ...rest]`.
The pipe operator draws on F# pipes, Hack pipes and the TC39 proposal. `data |> Object.keys |> console.log` becomes `console.log(Object.keys(data))`. Two details make it usable rather than a toy: single-argument arrow functions and the `&` shorthand tell the compiler how to use the left-hand side, and there are dedicated forms for `|> await`, `|> yield` and `|> return` so the value can be wrapped rather than merely passed.
Short function block syntax is the Ruby, Crystal and Elm inspired one. `x.map &.name` becomes `x.map(a => a.name)`. It nests, so `x.map &.profile?.name[0...3]` slices correctly, it supports calls with arguments as `x.map &.callback a, b`, and it handles unary and binary operators through `!!&` and `&+1`.
There are also custom infix operators derivable from any two-argument function, and `do`, `if` and `for` expressions rather than statements.
The catch is the same for all of them: this is a compiler with no GitHub releases, and a spec that is still a proposal is a spec that can change.
Block and JSX syntax is where most of the typing disappears
The ES6 conveniences are ordinary sugar, but they add up. Const assignment is `a := b`, and destructuring const is `{a, b} := c`. The let variant uses `.=`, so `a .= b`, and typed forms exist for both, `a: number .= 5`. The README flags the trap in the same breath: `a: number = 5` is not a typed let at all, it is the object literal `{a: (number = 5)}`. That is the kind of ambiguity that generates a bug report rather than a feature request.
Object shorthand goes further. `{foo()}` expands to `{foo: foo()}`, and `{props.foo}` becomes `{foo: props.foo}`, computed keys work, and `data.{x,y}` or `data{x,y}` produces `{x: data.x, y: data.y}`. A flagging shorthand borrowed from LiveScript writes `{+debug, -live, !verbose}` for a literal object of booleans.
The JSX changes are the ones that will save the most keystrokes in a component-heavy codebase. Instead of closing tags, you indent children and Civet closes them. Adjacent elements and fragments are combined automatically. Arrow function children need no braces, which the README justifies because `>` is not valid JSX text, so `<For> (item) => ...` is unambiguous. `#foo` is shorthand for `id="foo"`.
The README credits these to discussions in solid-dsl and to open JSX spec issues, which tells you the audience this was designed for.
Nine build integrations and a separate language server
The integration list is long enough that it is worth separating into two categories.
Tooling plugins exist for Vite, esbuild, Astro, Farm, Rolldown, Rollup and Webpack, and these are implemented as unplugins, which is the packaging format that lets one implementation serve several bundlers. Then there is a Babel plugin, an ESM and CJS loader, a Bun plugin, and a Jest integration, plus a documented `<script>` tag route for browser use. Starter templates exist for Solid and for Solid Start.
The breadth is the argument for Civet over a one-off build script: it is not a compiler you wire into your own pipeline, it is one that already knows how to sit inside the tools you already use.
The second category is the language tooling, and this is where a warning is due. The repository root has an `lsp/` directory, and package.json shows the documentation pipeline builds three separate workspaces before the site will compile: `lsp/server`, `lsp/monaco` and `civet.dev`. A language server and Monaco editor bindings are maintained separately from the compiler itself.
There is also a VS Code extension listed in the README, and a Playground at civet.dev. For a language at 0.11.16, the editor experience is the part most likely to lag behind the compiler, and it is worth installing both before committing to a project.
Testing the compiler with itself, and what version 0.11 means
The repository has an unusual self-hosting story that reveals how seriously the project takes its own correctness.
There is a `build:self` script that builds the compiler and then runs `build-self.sh`, and a `test:self` script that sets `CIVET_SOURCE=./dist/main.js` before running the full test suite, so the freshly built compiler is what executes the tests rather than a published version. Several other scripts are themselves written in Civet, including `typecheck-diff.civet`, `probe-shapes.civet` and the four coverage scripts. The test harness is configured through `.mocharc.json`, and coverage is tracked with codecov.
Release gating is strict in the same spirit: `prepublishOnly` runs the build, the coverage test suite and a changelog verification before anything is published.
The release process itself is `pnpm changelog --release`, driven by `build/changelog.civet`. There is no GitHub release for any version, and the npm version is 0.11.16. So CHANGELOG.md is the version history, which is unusual for an npm package and means your upgrade notes live in a file in the repository rather than in a release feed.
Two consequences follow. The project is clearly moving fast, with the last push on 2026-10-13. But nothing is semver-stable yet, there is no tag to pin against, and The package is currently at version 0.11.16, which is pre-1.0. For a team that wants to track versions through a package manager's release history, that is a real friction point.
Editorial conclusion
Adopt Civet if your team already writes TypeScript and spends real time on destructuring, object literals and JSX closing tags, because those are exactly what the shorthand removes, and the emitted TypeScript means your types, your bundler and your editor tooling survive unchanged. Do not adopt it for a library you publish source for, since consumers would receive compiled output unless you also publish the `.civet` originals, and do not adopt it while your editor tooling is still maturing, because the language server lives in a separate workspace and version 0.11.16 is pre-1.0 with no GitHub releases at all. Verify first that `civet --typecheck` covers your project rather than only your sources, and settle the question of whether CHANGELOG.md rather than release tags is what your team will track, because that is where this project's version history lives.
Frequently asked questions
How do I install and run Civet?
Install it with `npm install -g @danielx/civet`, then run `civet` for a REPL, `civet -c` for a REPL that outputs TypeScript, or `civet source.civet ...args...` to execute a single file.
Does Civet emit TypeScript or JavaScript?
It emits TypeScript. The quickstart shows `civet -c` as a REPL that transpiles typed Civet code into TypeScript, and `civet < source.civet > output.ts` for a file.
How do I type check a Civet project?
Run `civet --typecheck`, which requires TypeScript to be installed separately. The project itself runs the check against a tsbuildinfo cache at .cache/typecheck.tsbuildinfo.
Which build tools does Civet have plugins for?
The README lists plugins for Vite, esbuild, Astro, Farm, Rolldown, Rollup and Webpack as unplugins, plus a Babel plugin, an ESM/CJS loader, a Bun plugin, a Jest integration and a script tag route.
How often is Civet released?
The repository has no GitHub releases, and the npm package is at version 0.11.16. Version history lives in CHANGELOG.md, and the last push was on 2026-10-13.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/danielxmoore-civet)Was this useful?