npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@taiyakihitotsu/cion

v0.3.5

Published

Clojure implemented on TypeScript at the type-level.

Readme

Cion

npm license build

Cion is a full-featured, type-level Lisp interpreter inspired by Clojure.
Cion lets you execute Lisp code at compile time using TypeScript's type system.

type Result = Cion.Lisp<`(+ 1 2)`> // "3"

Try it:
playground | source

Install

pnpm - pnpm add -D @taiyakihitotsu/cion
npm - npm install -D @taiyakihitotsu/cion

Key Features

  • Zero Runtime Overhead: Computations are performed at compile-time and vanish in production.
  • Turing-Complete: Supports recursion, lexical scoping (let), and higher-order functions (fn), looping via let + fn or reduce.
  • Compile-time Regex: Features a built-in type-level regex engine (re-find).
  • Standard Library: 90+ built-in type-level functions including map, filter, reduce, and thread macros (->, ->>).

For Developers

If you want to understand the internal implementation, see DEV.md.

How to Use

import type Cion from '@taiyakihitotsu/cion'

const test: Cion.Lisp<`(inc 3)`> = '4'

Overview

Cion follows clojure's standard syntax. You can use builtins, vector [], and map {}.

Note

  • Lists () and sets #{} are not supported. Use vector instead.

(If you want to do a type-check of this doc, see test/test-in-doc.ts)

Basic

const test_in_doc3: Cion.Lisp<`(let [c {:status 'in' :message 'message1'} cc {:status 'out' :message 'message2'} cv [c cc cc] f (fn [a b] (= 'in' (b a)))] (->> cv (filter (fn [x] (= 'in' (:status x)))) first :message))`> = "'message1'"

Arithmetic

const test_in_doc_a0: Cion.Lisp<`(+ 2 3)`> = '5'
const test_in_doc_a1: Cion.Lisp<`(/ 2 3)`> = '2/3'
const test_in_doc_a2: Cion.Lisp<`(/ 2 0)`> = 'nil'
// @ts-expect-error: Type '"0"' is not assignable to type '"nil"'.
const test_in_doc_a2_err: Cion.Lisp<`(/ 2 0)`> = '0'
const test_in_doc_a3: Cion.Lisp<`(+ 2 (- 1 4))`> = '-1'
// @ts-expect-error: Type '"0"' is not assignable to type '"-1"'.
const test_in_doc_a3_err: Cion.Lisp<`(+ 2 (- 1 4))`> = '0'
  • Division by zero returns nil.
  • The value range is from -32767 to 32767. Numbers are internally handled as 16-bit signed integers. The minimum, -32768, is excluded currently.

Logical operation

const test_in_doc_log0: Cion.Lisp<`(> 3 2 1)`> = 'true'
// @ts-expect-error: Type '"true"' is not assignable to type '"false"'.
const test_in_doc_log0_err: Cion.Lisp<`(> 3 3 1)`> = 'true'

get

const test_in_doc_fst0: Cion.Lisp<`(first [1 2 3])`> = '1'
const test_in_doc_fst1: Cion.Lisp<`(first [])`> = 'nil'
// @ts-expect-error: Type '"[]"' is not assignable to type '"nil"'.
const test_in_doc_fst1_err: Cion.Lisp<`(first [])`> = '[]'
const test_in_doc_get0: Cion.Lisp<`(get [1 2 3] 0)`> = '1'
const test_in_doc_get1: Cion.Lisp<`(get [1 2 3] 4)`> = 'nil'
// @ts-expect-error: Type '"[]"' is not assignable to type '"nil"'.
const test_in_doc_get1_err: Cion.Lisp<`(get [1 2 3] 4)`> = '[]'
  • Accessing an out-of-bounds index returns nil.

if, let, fn

const test_in_doc_if0: Cion.Lisp<`(if true 1 2)`> = '1'
// @ts-expect-error: Type '"2"' is not assignable to type '"1"'.
const test_in_doc_if0_err: Cion.Lisp<`(if true 1 2)`> = '2'

const test_in_doc_let0: Cion.Lisp<`(let [a 2] (+ a 4))`> = '6'
// @ts-expect-error: Type '"5"' is not assignable to type '"6"'.
const test_in_doc_let0_err: Cion.Lisp<`(let [a 2] (+ a 4))`> = '5'

const test_in_doc_fn0: Cion.Lisp<`((fn [x y] (+ x y)) 2 3)`> = '5'
// @ts-expect-error: Type '"6"' is not assignable to type '"5"'.
const test_in_doc_fn0_err: Cion.Lisp<`((fn [x y] (+ x y)) 2 3)`> = '6'
  • Two-component if forms ((if true true-branch)) are not implemented.
  • Destructuring is not implemented.
  • Empty function bodies are not supported.

loop

type Loop_Return_4 = `(let [f (fn [r x] (if (>= 0 x) r (f (+ r 1) (- x 1))))] (f 1 3))`
const test_in_doc_loop0: Cion.Lisp<Loop_Return_4> = '4'
// @ts-expect-error: Type '"3"' is not assignable to type '"4"'.
const test_in_doc_loop0_err: Cion.Lisp<Loop_Return_4> = '3'
  • Use recursion like above. loop and recur are not implemented.

def, defn

def and defn is not implemented, but type typeof can be an alternative.

const test_in_doc_def0: Cion.Lisp<`(+ ${typeof test_in_doc_loop0} 5)`> = '9'
const test_in_doc_def1: Cion.Lisp<`(fn [i] (+ 1 i))`> = '(fn [i] (+ 1 i))'
const test_in_doc_def2: Cion.Lisp<`(${typeof test_in_doc_def1} ${typeof test_in_doc_def0})`> = '10'

type test_in_doc_def3 = `(+ 2 2)`
type test_in_doc_def4 = Cion.Lisp<`(+ ${test_in_doc_def3} 5)`>
type test_in_doc_def5 = '(fn [i] (+ 1 i))'
type test_in_doc_def6 = Cion.Lisp<`(${test_in_doc_def5} ${test_in_doc_def4})`>
const test_in_doc_def7: test_in_doc_def6 = '10'

re-find

const test_refind1 : Cion.Lisp<`(re-find '[a-z]*' 'aaa')`> = `'aaa'`
type email = `'(([^<>()[\\].,;: @"]+(\\.[^<>()[\\].,;: @"]+)*)|(".+"))@((\\[[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\])|(([a-zA-Z0-9-]+\\.)+[a-zA-Z]{2,}))'`
const test_refind : Cion.Lisp<`(re-find ${email} '[email protected]')`> = `'[email protected]'`
  • # of #'regex' is unnecessary.

Builtins

The specs of some fns don't follow Clojure.
See the spec directory.

Core

  • if, fn, let, nil

Arithmetic

  • +, -, *, /, mod, rem, *trunc, floor, inc, dec, abs, min, max

String & Regex

  • str, re-find, split, subs, *subs-all, replace, join

Logic

  • and, or, not, >, <, = (eq), >=, <=

Predicates

  • *prim?, any?, number?, string?, vector?, map?, fn?, ifn?, int?, *nat? (= nat-int?), ratio?, pos?, neg?, pos-int?, neg-int?, odd?, even?, zero?, keyword?, empty?, boolean?, type, every?, some, nil?, some?

Collections

  • map, filter, remove, reduce, zipmap, apply
  • conj, concat, interleave, reverse, range, repeat, drop, take, keys, count

Map operations

  • assoc, assoc-in, update, update-in

Accessors

  • first, second, *third, last, rest, butlast, get, get-in

Threading macros

  • ->, ->>, some->, some->>

And vector [0 1 2] & map {:x 0 :y 1 :z 2} syntax supported.

* indicates functions not available in Clojure.

Author

taiyakihitotsu

License

BSD 3-Clause License