Skip to content

QuickJS

Run JavaScript inside DuckDB SQL via the embedded QuickJS-NG engine.

24,966,945
extension loads · last 90 days
On this page

Technical Overview

An escape hatch to JavaScript, inside a SELECT

What this extension is for

  • Conditional JSON reshaping: When the output shape depends on values inside the input JSON, quickjs_eval with a per-row arrow function is more readable — and often faster to write — than a tower of CASE over json_extract.
  • Text munging beyond regex: Tokenizers, lightweight parsers, custom slug rules, normalization passes that depend on imperative control flow. JS gives you for, if, switch, and string methods without leaving SQL.
  • Array fan-out: The table form of quickjs lets a JS expression return an array and have DuckDB emit one row per element — handy for unrolling computed sequences or splitting a value into its components.
  • Reusing existing JS: Validation rules, formatting helpers, or small library snippets you already trust in JavaScript can be dropped into a query without rewriting them.

How it works

  • Two surfaces, picked by call site: quickjs used after SELECT evaluates an expression and returns a VARCHAR. The same name used after FROM expects an array and unpacks it into rows. quickjs_eval calls a JS function with positional arguments and returns JSON.
  • Argument binding: Positional arguments to the table form of quickjs are exposed inside the JS as arg0, arg1, … . When an argument is a JSON-shaped string, a parsed copy is also bound as parsed_arg0, parsed_arg1, … so you don't pay for JSON.parse in the snippet.
  • Modern ECMAScript: QuickJS-NG implements the bulk of the ECMAScript standard — arrow functions, destructuring, let/const, Map/Set, Promise, modern Array / String / Object methods. No browser, no Node APIs (no fetch, fs, etc.) — this is a pure language runtime.
  • Per-row evaluation: Snippets are JIT-compiled within the QuickJS context per call. There's no cross-row caching of compiled functions, so cost scales linearly with input row count.

When to reach for it (and when to stay in SQL)

  • Prefer native DuckDB functions: If DuckDB's scalar functions, json_* family, or regex functions cover your transform, they will be substantially faster — they run vectorized over column batches instead of one row at a time.
  • Hot OLAP paths are the wrong place: Per-row JS interpretation is fine for ETL and ad-hoc work over millions of rows. It is not the right tool for an interactive dashboard query that runs against a billion-row fact table on every refresh.
  • Untrusted input is risky: QuickJS is a sandbox in the sense that it has no I/O surface. It is not hardened against adversarial JS — don't quickjs_eval user-supplied source in a multi-tenant context.
  • Consider Rhai for tighter SQL integration: evalexpr_rhai embeds the Rhai scripting language. Rhai is more constrained as a language, but it tends to integrate more cleanly with SQL types — fewer JSON round-trips at the boundary. Worth comparing if your snippet is small and type-driven.

Common Use Cases

Deep Dive

Technical Details

Install

INSTALL quickjs FROM community;
LOAD quickjs;

Quick Start

Evaluate an expression

SELECT quickjs('2 + 2');

Call a JS function with arguments — return value is JSON

SELECT quickjs_eval('(a, b) => a + b', 5, 3);

Table form: JS returns an array, DuckDB unpacks it into rows

SELECT * FROM quickjs('[1, 2, 3, 4, 5]');

Reference

Extension Contents

Quick reference to all available functions and settings organized by category.

Name Description
Execute
quickjs() Evaluate JavaScript code and return the result.
quickjs_eval() Call a JavaScript function with the given arguments.

API Reference

Function Documentation

Practical Examples

Cookbook

Real-world recipes and patterns for common use cases.

Platform Support

Compatibility

Extension availability may vary by platform and DuckDB version. Check below to ensure this extension supports your environment before installation.

Quick Facts

Release status Stable
Software License MIT
Pricing Free
Written In C++
Source Available Yes
View on GitHub
Usage
24,966,945
loads · last 90 days

Platforms

  • Linux x86_64 aarch64
  • Linux (musl) Not available
  • macOS Intel Apple Silicon
  • Windows x86_64
  • WASM eh mvp threads
Compiled binary sizes
Platform Architecture Size
Linux x86_64 3.68 MB
Linux aarch64 3.29 MB
macOS Intel 1.89 MB
macOS Apple Silicon 1.71 MB
Windows x86_64 7.79 MB
WASM eh 299.4 KB
WASM mvp 293.3 KB
WASM threads 299.5 KB

Compressed download size from the Haybarn extension repository.

DuckDB & Haybarn

Release calendar