Fork me on GitHub

Duktape

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.


Main features


Code and RAM footprint

 x86 defaultx86 lowmemx86 full lowmem
Code170kB150kB200kB
Startup RAM68kB35kB2.3kB

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.


Current status


Support


Some projects using Duktape

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.


Similar engines

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

Also see List of ECMAScript engines.


1 Add to build

(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.1.0/tools/configure.py --output-directory src-duktape \
      -UDUK_USE_ES6_PROXY
$ 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

2 Initialize a context

Initialize and use Duktape somewhere in your program:

/* test.c */
#include <stdio.h>
#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=%d\n", (int) duk_get_int(ctx, -1));
  duk_destroy_heap(ctx);
  return 0;
}

3 Add C function bindings

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

/* Being an embeddable engine, Duktape doesn't provide I/O
 * bindings by default.  Here's a simple one argument print()
 * function.
 */
static duk_ret_t native_print(duk_context *ctx) {
  printf("%s\n", duk_to_string(ctx, 0));
  return 0;  /* no return value (= undefined) */
}

/* Adder: add argument values. */
static duk_ret_t native_adder(duk_context *ctx) {
  int i;
  int n = duk_get_top(ctx);  /* #args */
  double res = 0.0;

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

  duk_push_number(ctx, res);
  return 1;  /* one return value */
}

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

duk_push_c_function(ctx, native_print, 1 /*nargs*/);
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));");

Duktape is (C) by its authors and licensed under the MIT license.