
Duktape: an embeddable JavaScript engine - bpierre
http://duktape.org/
======
haberman
Very, very cool.

I've lamented for a while that, while JS engines are flourishing from a speed
perspective, there has never been one as small or embeddable as Lua.

Now we have JS as embeddable as Lua, and nearly as small (it probably can't be
_quite_ as small because Lua is a simpler language).

Now the only thing Lua has on JS, implementation-wise, is an implementation
that is very small/embeddable _and_ very fast (LuaJIT). LuaJIT is also about
as small as a JIT-compiled interpreter can be.

But it looks like Tessel is working on filling that gap as we speak -- they
are working on targeting LuaJIT for their JavaScript implementation
[http://blog.technical.io/post/102381339917/a-new-engine-
for-...](http://blog.technical.io/post/102381339917/a-new-engine-for-your-
tessel)

~~~
munificent
> Now the only thing Lua has on JS, implementation-wise, is an implementation
> that is very small/embeddable and very fast (LuaJIT).

Well, and a simpler, more regular syntax. Simpler semantics. Real coroutines.
Tail call elimination. Multiple returns. Better iteration syntax and protocol.
Better lexical scope. Operator overloading. A well-established FFI. No weird
variable hoisting, nasty implicit conversions, semicolon insertion, etc.

But, sure, aside from those things, Lua doesn't have anything on JS as a
language. (Of course, as an ecosystem, JS is miles ahead.)

~~~
hajile
Those are all very important comparisons (and I would add that both Lua and JS
got the global by default thing wrong0. I would note that ES6 requires proper
tail calls and that trampolining can accomplish tail call elimination (tail
call elimination is different than proper tail calls).

The major issue to me is time. I know quite a few languages, but have only
mastered a couple. JS is everywhere and the browser makes sure this will be
the case for a long time.

The issue is that these advantages do not outweigh the ubiquitous nature of
JavaScript. If I already need to learn all of those JS quirks, why learn Lua
too?

~~~
chii
because learning isn't something you stop doing?

Also, lua is a nicer language, and if you have the choice, you should chose it
over js.

~~~
Aldo_MX
> Also, lua is a nicer language, and if you have the choice, you should chose
> it over js.

Sorry, but I prefer the nasty language with 0-indexed arrays.

------
creationix
If anyone is wanting a node.js like experience with duktape, I've been working
on libuv bindings for duktape.

[https://github.com/creationix/dukluv](https://github.com/creationix/dukluv)

~~~
vvpan
I want to use it for the name alone

~~~
creationix
[http://dukluv.io/](http://dukluv.io/)

------
cdnsteve
Could someone clarify why you'd want to have a JavaScript engine in your C/C++
Project?

Is the idea if you have a desktop app executable wrapper and you could include
this engine to start building desktop apps in JavaScript?

I don't think I have a clear understanding of this type of use case or how
this will be used, please share.

The only thing I can think of is you could use this JS engine allow folks to
code in JS, instead of C/C++, that actually interface with C/C++ APIs?
Examples anyone?

~~~
ender7
There are lots of reasons to want some form of scripting language embedded
inside a C++ project. This is the primary use case for Lua, especially in game
development. For example

\- In a game, write quest logic in the scriptable language so that game devs
can tinker with quest design without recompiling the game binary.

\- "plugins" (usually UI plugins of some kind). Games like Elder Scrolls
Online and World of Warcraft allow for 3rd parties to write UI extensions in
Lua.

\- Any other logic that you want to run and frequently modify without
modifying the binary.

There are other great uses-cases that I can't think of right now, hopefully
others can help.

~~~
kristiandupont
Another one could be:

\- You already have working JS code that you don't want to rewrite for a new
platform

~~~
unsigner
Any non-trivial JS code is likely to be closely tied to the original
platform/runtime for which it was meant, and thus hard to port. (Vs. purely
computational)

~~~
xdenser
I have experience of porting JS code from one environment to another. First I
was using Delphi Application with MS Active Scripting and MS JScript Engine
then moved to nodejs on linux, then back to windows on nodejs, and still have
JS code originally written for MS Active Scripting. With nodejs vm module you
may create needed context. I also was successfully using socket.io and code on
top of it with MS Active Scripting based application by implementing simple
WebSocket wrapper to Delphi component.

------
chj
Duktape seems to be based on the same principle of sqlite3. Distributed as one
big c file. Really cool.

Another note: Try to do fib(33) in duk, it takes 9s, while lua interpreted
mode takes under 2s. So no doubt it's still got a long way to go in terms of
performance.

~~~
svaarala
Very little performance work has been done so far. Most of the effort has been
in E5 compliance and more recently to support low memory environments (96-128
kB system RAM) better. But there's going to be performance work early next
year.

------
mrinterweb
Out of sheer curiosity, I wonder if duktape can run node? If so, I would think
it to be possible to repackage node libraries as ruby gems. Not saying this
would be a good idea, I am just wondering if it would be possible.

~~~
troels
Ruby gems? How'd you figure that?

~~~
BillinghamJ
You can very easily expose C/C++ libraries to Ruby. Totally native too - not
hacking it together.

~~~
troels
Right - but node.js is already a C++ project, so I don't see the difference?

------
joev_
Obligatory:

[http://jsfiddle.net/jrxvw1yd/](http://jsfiddle.net/jrxvw1yd/)

Compiled through emscripten to build a JS interpreter in a browser... at only
1.5MB!

------
regecks
A bit disappointed at its heavy use of macros, makes it a fair bit harder to
link to from other languages (just sat down to write bindings for this, and
realized it'll involve a lot of rewriting).

Disappointed mainly because the fact of no platform dependencies and two
simple files would have made it a very very convenient library even from
non-C.

~~~
yoklov
The macro usage might look daunting but most of it is pretty typical for
libraries without platform dependancies (lots of compiler dependant config and
shims for missing libraries).

Look for "BEGIN PUBLIC API" for the stuff you'd have to wrap. Stop at "END
PUBLIC API". Nothing there should be that weird looking.

------
jamesu
I checked out duktape a while ago and found the documentation quite
impressive. Although it didn't seem to have too many examples regarding how to
embed into a typical app (with class hierarchy, etc).

Also like a lot of these other "lua alternatives", it's interesting to note
development seems to be driven mostly by one guy... which if you want to use
it in a project brings up the question: "What if they get hit by a bus?".

~~~
creationix
A lot of these one-man projects aren't because nobody else in the world can
work on them. It's usually because everyone else is busy working on something
else.

If I ended up having to maintain duktape I'm confident I could understand and
improve the code with a little rampup time. This isn't rocket science. The
hardest problem is finding time and funding. If a company depends on the
project they have incentive to provide those things.

------
valarauca1
Just yesterday I was looking for a simple C based javascript engine. Thank
you.

~~~
robert_tweed
Here's a C++ one:

[https://code.google.com/p/tiny-js/](https://code.google.com/p/tiny-js/)

I started using it for a small side-project but had to put it on hold because
of issues elsewhere in the stack.

From a cursory glance at things, Duktape looks way more advanced, and being
written in pure C should make it much easier to embed. I'll definitely give it
a try when I have time to look at that project again.

That said, the TinyJS code is _extremely_ simple, so it makes a potentially
good starting point for extending, if you want something JS-like rather than a
pure JavaScript engine.

~~~
valarauca1
I'm not a huge fan of C++. And that's primarily out of ignorance, I stick with
C and leave all the strange syntax wizardy, templates, metatypes to other
people.

Also the portability of Duktape impressed me. I was able to get a test up and
compiled in cygwin within a few minutes.

------
analog31
Maybe I'm asking a dumb question, but does this mean I can stick JS onto a
microcontroller of my choice, just by wrapping it in a C program? I wonder how
big it is when compiled.

Edit: I see the requirements are right there.

~~~
svaarala
Around 200kB of code (flash), and around 25kB of RAM after startup, with low
memory optimizations in the master branch (for the upcoming Duktape 1.1
release). This doesn't include User Javascript, just what Duktape needs to
start up.

You can run Duktape with 128kB RAM, and to some extent with 96kB, see e.g.:
[http://www.slideshare.net/seoyounghwang77/js-
onmicrocontroll...](http://www.slideshare.net/seoyounghwang77/js-
onmicrocontrollers)

------
mamod
I've been using duktape for some while now and it's totally amazing, for the
wonder minds about why using duktape instead of V8 or SM here's some of my
list

First of all duktape written in C not C++ I hope this is a good point for you
as it was for me :)

Not everyone seeks speed, for me, simplicity and ease of use beats speed any
given day, after all I'm not after complex computations and fib that loops for
ever :) one file to include and pretty sure it well compile in many platforms
to get a full working Ecmascript E5/E5.1 how awesome!

Compilation time, don't know about current SM compilation time but I tried
once to compile V8 and I still feel sorry for doing that to my poor old
machine :)

Memory management, I'm not sure how, but duktape's GC is amazing.

Last and the most appealing point for me "unfortunately no one mentioned that
yet" is documentations, I don't mean just api, please visit duktape.org and
see how beautiful well written everything there, Sami "the author" put a great
effort not just to write duktape but it's documentation too, api, usage,
comments, specifications, examples ... and best of all it was clear and very
easy to follow.

The only thing I hope is more people join to help Sami maintain the project,
currently the man is very active and responsive, but I think the project will
expand in the next few weeks with more and more users, so I guess he will need
some help then :)

------
pmontra
It serves a different purpose, but speaking of tiny JavaScript interpreters
there is also the one for the Espruino boards. Last time I checked it was said
to be 95% compatible, but I don't now against which specification. Probably
it's OK for most tiny applications anyway.

Source code at
[https://github.com/espruino/Espruino](https://github.com/espruino/Espruino)

Espruino boards at [http://www.espruino.com/](http://www.espruino.com/)

------
SCHiM
You've got to love it when a library is at that point where ease-of-use and
features perfectly intercept.

This library is great:

On the simplicity side:

Only include two files, no linking, no shared objects, no cruft.

On the feature side:

The functions are simple, the usage-pattern is familiar (alloc, use, free) and
the code is fast (written in C, which _almost_ makes it fast by default).

Great library, will probably use it when I need to write some more scrapers in
the future.

~~~
munificent
> the code is fast (written in C, which _almost_ makes it fast by default).

I hate to be that guy, but [Citation Needed].

Most language implementations are written in C and most language
implementations are quite slow, once you include the giant slew of hobby, toy,
and less successful languages. Remember, Ruby, Python, and early versions of
JS interpreters were all written in C too and are or were dog slow!

Duktape does have a section on performance[1], but it's basically just a guide
to things _you_ have to do to not make it extra slow. I didn't see any
reported benchmarks.

This doesn't mean Duktape is bad. Simple+slow is a perfectly good trade-off
for many real-world uses. Embedded scripting languages tend to spend most of
their time in the FFI, not executing code, so perf doesn't matter as much as
maintainability.

But it's really dubious to just say, "well, it's written in C so it's probably
great." It's using ref-counting and linear scanning or hash table lookup for
property look-up. Perf is likely _not_ great.

Just as a point of comparison, my little hobby language[2] is also written in
very simple C, but it's carefully designed to be fast too. Property look-up
and method calls are just pointer + known offset. GC is tracing. Because of
this (and other stuff), perf actually is good[3], typically better than Python
and Lua and on par with Ruby. (With the usual caveat that all benchmarks are
bad. :) )

[1]:
[http://duktape.org/guide.html#performance](http://duktape.org/guide.html#performance)

[2]: [https://github.com/munificent/wren](https://github.com/munificent/wren)

[3]:
[https://github.com/munificent/wren/blob/master/doc/site/perf...](https://github.com/munificent/wren/blob/master/doc/site/performance.markdown)

~~~
coldtea
> _Most language implementations are written in C and most language
> implementations are quite slow_

That's not a fair comparison. Speed is relative. Compare them to
implementations written in other languages.

~~~
munificent
I think even then, you'd find C isn't particularly fast if you consider the
mean speed of all languages implemented in it.

Languages that have decent implementation speed are a rare outlier compared to
the hordes of slow implementations out. That horde of slow languages is wide
enough to also encompass slow implementations in other languages too.

------
mempko
seems the C interface is modelled after Lua. Is there any inspiration there?

~~~
svaarala
Absolutely, the original motivation was to have a Lua-like implementation for
Javascript.

~~~
Aldo_MX
I really want to applaud your effort. Are you accepting donations?

~~~
svaarala
Thanks! At the moment no, but send me an e-mail if you use Duktape somewhere
:)

------
dark12222000
We need to have Node bindings so we can javascript in our javascript.

~~~
pedalpete
It's been done [http://dukluv.io/](http://dukluv.io/)

~~~
creationix
Actually dukluv is the other way. It's a re-implementation of of a node-like
environment using duktape instead of V8. I think the original question here
was to write a node addon that allowed you to run arbitrary code in a duktape
sandbox.

------
brent_noorda
Very happy to see this effort. Until about 2004 my little company licensed an
embeddable javascript engine written in C. For the past decade I've continued
to provide free support and advice for the old customers, but haven't been
able to point them to any new engines with a good API, customizability, small
footprint, and licensing to replace our old Nombas engine. From the guide and
API duktape looks like it might be the one! Thanks, Sami et al.

------
Animats
This is a useful little piece of code, but it has risks if users are allowed
to insert Javascript in something running elsewhere. That might happen if
you're writing a multiplayer game where users can add content. Or using it in
a browser-like environment. How much power does that Javascript have? How well
is it sandboxed? What about buffer overflows?

------
asimjalis
Are there any tools to create a single binary from JavaScript (using Duktape
or some other embeddable JS engine)? I am thinking about the deployment
scenario here. In its current form Duktape shipping a binary and a JS file
separately. Is there a way to “compile” the JS file into the C file and
produce a single binary?

~~~
chii
it's pretty trivial to do that - just define a macro and use it to insert the
contents of a _.js file into the_.c file, and use it as a string like in the
sample program.

------
RyJones
We use Duktape at AllSeen Alliance (disclaimer: I work there) to put
JavaScript bindings on small devices.

[https://git.allseenalliance.org/cgit/core/alljoyn-
js.git/sum...](https://git.allseenalliance.org/cgit/core/alljoyn-
js.git/summary)

~~~
errordeveloper
It's pretty cool indeed what you guys are doing with it, although currently
there are not as many MCUs where Duktape fits... The STM32F4 Discovery board
that AllJoyn+Duktape targets, is the same one Java Embedded also runs on,
IIRC. From my knowledge the STM32F4's are some of the fatter micros currently
on the market.

------
user_id2
Just when you were asking yourself "how can I avoid any future responsibility
for maintaining this code and meeting my customers' usecase, while having
industry support for my lack of responsibility?"

Why not just embed an API and call it SQL.

------
drew-r
Any C# bindings?

~~~
arethuza
I've used Jint (a JavaScript interpreter written in C#) in a couple of
projects:

[https://jint.codeplex.com/](https://jint.codeplex.com/)

------
chrischen
Is this going to be much more efficient than embedding v8 in php?

~~~
creationix
It a couple orders of magnatude slower, but smaller than V8. I love the low
overhead and have been using duktape for some time.

~~~
donpdonp
How does duktape compare to v8? I've been happy with the ruby gem
'therubyracer' to evaluate javascript inside a ruby app. Method calls work
both ways Ruby<->JS, etc.

------
achalkley
I'd like to see this running on an Arduino :)

~~~
mmastrac
I thought about this, but at least the atmega328p has nowhere near enough RAM
for it. The Arduino Mega's chip is still a bit small (ref this comment [1])

[1]
[https://news.ycombinator.com/item?id=8702610](https://news.ycombinator.com/item?id=8702610)

~~~
svaarala
These amount of flash/RAM are probably not realistic for a compliant engine.
For instance, the Duktape regexp engine alone takes around 10kB flash
compiled.

Luckily Javascript has a great ecosystem, so there are non-compliant subset
engines targeting tiny devices. What other (higher level) language scales this
way? :)

------
en4bz
Why would I choose this over SpiderMonkey/V8?

~~~
creationix
It's worlds smaller and easier to work with.

Integrating duktape into my project was literally just including the C file.
It added just a couple hundred KB of overhead.

Compare that to SM or V8 that require massive custom build systems and use up
to 10mb of ram for a simple repl.

~~~
errordeveloper
Well, not exactly, Espruino is way smaller. However, Duktape is fully-
compliant ECMAScript interpreter.

------
ColinWright
It would be nice if the title gave a clue about the content. I know the mods
are busy, but perhaps it could be changed to something like:

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

Without that, the title is effectively click-bait, requiring a click just to
find out what it's about.

 _Edit: I see it 's changed - thank you mods, or contributor._

~~~
pselbert
Absolutely. The lack of context prevented me from clicking on the link at all.
Thanks for providing a description.

------
swah
IMO the killer app today is compiling React server-side, and fast! I'd use
that in Go...

~~~
xanderjanz
Sounds like you're looking for Rendr.

~~~
swah
Not everyone wants to use Node...

~~~
xanderjanz
Why not use a node script for this one part? Seems to me pretty wise to use a
javascript runtime when evaluating javascript. You can still use Go or
whatever else for all your other tasks.

~~~
swah
Just simplicity of the deployment. Now I think the right solution is an RPC to
a NodeJS server, like you said.

------
mkevac
Nothing to see here. Come along. Just one guy that wrote whole JS interpreter
in his free time. Holy shit!

------
kornakiewicz
Question I got to ask: why? Maybe my understanding is wrong, but it's look
like including car's spare wheel to a space shuttle.

