Duktape is an embeddable Javascript engine,
with a focus on portability and compact footprint.

Duktape is easy to integrate into a C/C project: add duktape.c,
duktape.h, and duk_config.h to your build, and use the
Duktape API to call ECMAScript functions from C code and vice versa.

  • Embeddable, portable, compact:
    can run on platforms with 160kB flash and 64kB RAM
  • ECMAScript E5/E5.1,
    with some semantics updated from ES2015
  • Partial support for
    ECMAScript 2015 (E6) and
    ECMAScript 2016 (E7), see
    Post-ES5 feature status and
  • ES2015 TypedArray
    and Node.js Buffer bindings
  • CBOR bindings
  • Encoding API bindings based on the WHATWG Encoding Living Standard
  • performance.now()
  • Built-in debugger
  • Built-in regular expression engine
  • Built-in Unicode support
  • Minimal, retargetable platform dependencies
  • Combined reference counting and mark-and-sweep garbage collection
    with finalization
  • Coroutines
  • Property virtualization using a subset of ECMAScript ES2015 Proxy object
  • Bytecode dump/load for caching compiled functions
  • Distributable includes an optional logging framework, CommonJS-based module
    loading implementations, etc
  • Liberal license (MIT)

For a “Hello world” example:

Config Code footprint (kB) Startup RAM (kB)
thumb default 148 78
thumb lowmem 96 27
thumb full lowmem 119 1.5
x86 default 187 78
x86 lowmem 124 27
x86 full lowmem 148 1.5

See GCC options
for minimizing code footprint. Full lowmem
uses “pointer compression” and ROM-based strings/objects. ROM-based strings/objects can
also be used without other low memory options.

  • Stable

See: Projects using Duktape.

If you’re using Duktape in your project, send an e-mail or open a GitHub
issue to be added to the list.

There are multiple Javascript engines targeting similar use cases as Duktape, at least:

Also see List of ECMAScript engines.

(See Getting started for a more
detailed introduction.)

Add Duktape C source and header to your build. Any build system can
be used. The distributable contains an example Makefile for reference.
In the simplest case:

$ gcc -std=c99 -otest test.c duktape.c -lm
$ ./test
1 2=3

To customize Duktape configuration,
here to disable ECMAScript 6 Proxy object support:

$ python2 duktape-2.5.0/tools/configure.py --output-directory src-duktape 
$ ls src-duktape/
duk_config.h  duk_source_meta.json  duktape.c  duktape.h
$ gcc -std=c99 -otest -Isrc-duktape 
      test.c src-duktape/duktape.c -lm
$ ./test
1 2=3

Initialize and use Duktape somewhere in your program:

#include "duktape.h"

int main(int argc, char *argv[]) {
  duk_context *ctx = duk_create_heap_default();
  duk_eval_string(ctx, "1 2");
  printf("1 2=%dn", (int) duk_get_int(ctx, -1));
  return 0;

To call a C function from ECMAScript code, first declare your
C functions:

static duk_ret_t native_print(duk_context *ctx) {
  printf("%sn", duk_to_string(ctx, 0));
  return 0;  

static duk_ret_t native_adder(duk_context *ctx) {
  int i;
  int n = duk_get_top(ctx);  
  double res = 0.0;

  for (i = 0; i < n; i  ) {
    res  = duk_to_number(ctx, i);

  duk_push_number(ctx, res);
  return 1;  

Register your functions e.g. into the global object:

duk_push_c_function(ctx, native_print, 1 );
duk_put_global_string(ctx, "print");
duk_push_c_function(ctx, native_adder, DUK_VARARGS);
duk_put_global_string(ctx, "adder");

You can then call your function from ECMAScript code:

duk_eval_string_noresult(ctx, "print('2 3='   adder(2, 3));");