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

kei-lisp

v2.2.0

Published

A Lisp interpreter implemented in TypeScript

Readme

kei-lisp

npm version License: MIT Node.js

A Lisp interpreter implemented in TypeScript. Use it from the command line as an interactive REPL, or embed it in your application as a library.

Features

  • Common Lisp-inspired syntax (setq, defun, let, cond, ...)
  • CLI tool and embeddable library
  • ESM and CommonJS dual output with TypeScript types
  • Zero runtime dependencies

Installation

# Use as a CLI tool
npm install -g kei-lisp

# Use as a library
npm install kei-lisp

Requires Node.js >= 24.

Quick start

CLI

$ kei-lisp
>> (+ 1 2 3)
6
>> (defun square (x) (* x x))
square
>> (square 7)
49
>> (exit)
Bye!
kei-lisp --version  # Show version
kei-lisp --help     # Show help

Library

import { LispInterpreter, Cons } from 'kei-lisp';

const interpreter = new LispInterpreter();
const result = interpreter.evalString('(+ 1 2 3)');
console.log(Cons.toString(result)); // "6"

CommonJS is also supported:

const { LispInterpreter, Cons } = require('kei-lisp');

API

| Export | Description | | ------------------- | ---------------------------------------------------------- | | LispInterpreter | Programmatic interpreter (parse / eval / environment) | | Repl | Interactive REPL on stdin / stdout | | Cons | Cons cell (pair) data type with type predicates | | InterpretedSymbol | Lisp symbol (interned) | | KeiLispError | Base class for parse / eval failures (subclass of Error) | | ParseError | Thrown on parse failure (subclass of KeiLispError) | | EvalError | Thrown on evaluation failure (subclass of KeiLispError) | | ExitError | Thrown when (exit) is evaluated; catch to handle exit |

LispInterpreter

const interpreter = new LispInterpreter();

// Evaluate source and return the last expression's result
interpreter.evalString('(+ 1 2)'); // 3

// Evaluate multiple expressions and return all results
interpreter.evalAll('(setq x 10) (* x x)'); // [10, 100]

Repl

import { Repl } from 'kei-lisp';

// Start an interactive REPL on stdin/stdout
new Repl().run();

Error handling

evalString, evalAll, eval, and parse throw on failure. Catch the errors at the boundary; ExitError is intentionally separate from the KeiLispError family so a generic Lisp-error catch does not swallow it.

import { LispInterpreter, KeiLispError, ExitError } from 'kei-lisp';

const interpreter = new LispInterpreter();
try {
  interpreter.evalString(userInput);
} catch (error) {
  if (error instanceof ExitError) {
    // Lisp called (exit) — graceful shutdown
    return;
  }
  if (error instanceof KeiLispError) {
    // ParseError or EvalError — display to user and continue
    console.error(`${error.name}: ${error.message}`);
    return;
  }
  throw error;
}

Examples

Arithmetic

(+ 1 2 3)   ;; => 6
(- 10 3)    ;; => 7
(* 4 5)     ;; => 20
(/ 100 4)   ;; => 25
(mod 10 3)  ;; => 1

Lists

(list 1 2 3)            ;; => (1 2 3)
(car (list 1 2 3))      ;; => 1
(cdr (list 1 2 3))      ;; => (2 3)
(cons 0 (list 1 2 3))   ;; => (0 1 2 3)
(length (list 1 2 3))   ;; => 3

Defining functions

(defun factorial (n)
  (if (= n 0) 1 (* n (factorial (- n 1)))))

(factorial 10)  ;; => 3628800

Conditionals and bindings

(if (= 1 1) "yes" "no")                       ;; => "yes"
(cond ((= 1 2) "a") ((= 1 1) "b") (t "c"))    ;; => "b"
(let ((x 10) (y 20)) (+ x y))                 ;; => 30

Runnable TypeScript examples live in examples/:

pnpm build  # build the package once
pnpm exec tsx examples/basic-eval.ts
pnpm exec tsx examples/exit-handling.ts

Reference

In-depth documentation of each language area:

Development

git clone https://github.com/ike-keichan/kei-lisp.git
cd kei-lisp
pnpm install
pnpm start

Requires pnpm and Node.js 24+ (see .node-version for the exact version).

| Command | Description | | ----------------- | ----------------------------------------- | | pnpm build | Build for distribution | | pnpm start | Run the built CLI | | pnpm test | Run tests | | pnpm test:watch | Run tests in watch mode | | pnpm check | Run all checks (format, lint, spell, ...) | | pnpm fix | Auto-fix format and lint issues |

License

MIT