Table of Contents
1 What is JXCore?
JXCore is an open source project under an MIT license at Github. It’s created by a company called Nubisa. What Nubisa has done is take Node.js (mostly 0.10.36) and forked it. But the purpose of their fork is to add in three features that they hope they will eventually get to give back to Node.js.
The first feature is multi-threading support. This allows them to run separate parallel instances of node.js at the thread level. Typically to do that in Node.js one has to run multiple processes. By using threads instead the cost of running parallel instances goes down and of course inter-instance communication can potentially be done much more cheaply.
The third feature is packaging. Nubisa can take a whole group of Node.js related files and put them together into a single executable. This makes deploying and moving them around much easier. They also have technologies to make it difficult to reverse engineer the source code.
Because of how JXCore is written (more detail below) anything that runs in Node 0.10.36 should more or less run in JXCore. Where there are differences it’s mostly due to issues of running on mobile platforms like Android and iOS.
2 Who is Nubisa anyway?
Near as I can tell they are a small self funded start up split between Boston and Poland. They have been around for 2 years now. Apparently they always wanted to target the mobile market but pivoted and decided to first target dense node.js hosting via their multi-threading support. Since each thread is an isolated instance of node.js this means that ISVs can use JXCore to host node.js more densely than is apparently possible with Node.js’s native process level isolation model.
- JSC is LGPL. If you dynamically link a LGPL library then all is good. But if you link a LGPL library statically then you are required to release your source code.
4 So we can use v8 on iOS with JXCore?
No! Apple apparently bars JIT’ing so we can’t run v8 straight out. There is however a virtual machine “mode” in v8 where it can apparently output the JIT’d instructions and then interpret them rather than execute them. And yes, I’m told this is as horribly slow as it sounds.
5 So we have to use SpiderMonkey on iOS?
6 Do we also have to use SpiderMonkey on Android?
No, v8 is fully supported on Android.
7 How much of Node.js’s built in libraries actually work on JXCore?
Node.js's libraries are a core part of its value. So below I look at the state of those libraries in JXCore.
The following libraries just plain work - Buffer, Crypto, Domain, Events, Globals, HTTP, HTTPS, Net, Path, Punycode, Query Strings, Stream, String Decoder, Timers, TLS/SSL, UDP/Datagram, URL, Utilities, VM and ZLIB.
The libraries below work but have some edge case issues, mostly due to the inherent nature of the underlying mobile platforms.
DNS It should work but unfortunately different platforms, especially iOS, have weird behavior around DNS. There is more testing needed here to be sure this works correctly.
File System Some functions supported by node.js just plain don’t work on some platforms. For example, iOS does not have any native support for watchfile. iOS also has its own layout for storage dividing things up into app storage, document storage, etc. iOS also only provides access to a storage sandbox, not the whole drive. JXCore has worked around most of these limitations putting in code that feels more or less natural. In some cases they had to fake output. For example if someone runs stat on one of the node.js files on Android there is no actual file since the data is pulled out of the assets compressed folder. So they return fake stat results to compensate. But in general it should work.
Modules With the exception of native modules this works.
OS Much like file system there are aspects of mobile OS’s that don’t always have equivalents on all mobile platforms but in general JXCore tries to fake them where necessary.
Process Same issue as with File System and OS. Some commands, like cwd, can get very tricky on iOS because of its unique approach to managing files. They work hard to put in “fake” behaviors that do reasonable things.
These next libraries don’t work at all and frankly, shouldn’t. They just don’t make much sense on a mobile platform.
C/C++ Addons This actually might work “as is” on Android for developers who are using the v8 engine plugin. But in general this won’t work because JXCore’s whole point in existence is to provide an engine neutral API. The existing C/C++ Addons in Node.js are completely v8 specific.
Child Processes No. This library creates separate process instances of node.js. That is very heavyweight and probably not appropriate for a mobile platform.
Cluster This is for creating clusters of node.js machines that can share load. Not appropriate for mobile.
Console Mobile app models don’t really support a console. Therefore JXCore uses the console for logging.
Readline As with Console there is really no command line in the mobile execution models so this doesn’t make sense.
REPL As with Console and Readline there is no command line so there is no where to run a REPL from.
TTY No. On Android, since there is no console, they hijack standard in/out for logging. On iOS there really is no equivalent.
And finally, and sadly, the Debugger library just plain doesn’t work. This is a bug though and needs to be fixed. But it’s still pretty impressive that this is the only “total outage” in terms of JXCore’s support for Node.js’s libraries.
8 Will Node.js native add-ons run on JXCore?
In the long run the hope is to enable the JXCore native add-on interface to work with standard Node.js. In that case a native add-on written for JXCore could work both with JXCore and with mainline Node.js. There is also a theoretical possibility of getting something like nan to work with JXCore.
But in general existing native add-ons just plain won’t work “as is” with JXCore.
The more interesting question is - does it matter that existing native add-ons won’t run “as is”? It’s hard to say really. It depends on what you are trying to do. I looked at this question in some detail previously and assuming there isn’t some huge error in my logic it doesn’t seem like native add-ons are all that popular.
Still, I know the JXCore folks are working on porting over the most popular native add-ons.
9 How is the perf?
I have a whole article that explores this. But the summary is that node.js on a modern phone runs around 10x slower than on a modern PC. Which, honestly, isn’t bad!
10 How different is JXCore’s code from node.js? Can they really RI from Node.js?
To help me understand the answer to these questions I took the JXCore code and diffed it with the Node.js code. I was trying to see how different the two code bases are and how readable JXCore’s code is.
My general conclusion is that their code is readable, their changes make sense and other than the changes they made in the src directory I think RI’ing everything else would be fairly straight forward. I do think that RI’ing to the src directory is doable but it requires someone who has an intensely intimate understanding of the JXCore macro layer and JXCore’s functional extensions and even then I bet that for just about anyone but Nubisa’s CTO Oguz Bastemur, it would take a solid two or three weeks to RI to src.
One thing I did notice is that the code is a bit of a Frankenstein’s monster. There is code from 0.10.26, 0.10.29, 0.10.36 and some even from the master branch of Node.js. I talked with the Nubisa folks about this and they explained that they weren’t always happy with some of the changes that Node.js made and so they picked and choose which changes they took. In many cases they felt vindicated in their choices when it turned out that later Node.js would actually roll back a change that Nubisa didn’t like. The Nubisa folks have promised to release a doc on GitHub explaining their choices.
Below I walk through the major directories in the JXCore distribution and explore what the code looked like and how different it is from Node.js.
Root files Most of these files look like v0.10.26 and required some surgery to common.gypi, configure, Makefile and vcbuild.bat. But the changes all makes sense. Mostly adding build targets, removing targets like uploading to node.js’s website, etc. Nothing particularly thrilling.
benchmark Mostly identical, very few changes.
build_scripts These are android/ios utilities provided by JXCore, not part of Node.js.
deps Deps contains a bunch of sub-directories with the major dependencies so what is most interesting is what is in those sub-directories. So I list them individually below.
deps/cares No substantive changes.
deps/http_parser No substantive changes.
deps/npm The key file here is package.json. The only interesting thing is that the file appears to be from v0.10.29. JXCore also added some extra entries to the package.json file included with Node.js.
deps/openssl They are using the same release of opensll as Node.js master. Which makes sense. This is code that must be kept up to date.
deps/sqlite This is included by JXCore and isn’t part of Node.js.
deps/uv The files look like a mishmash of v0.10.26/v0.10.29. But the actual changes are minor. The biggest change is that JXCore really doesn’t like ngx-queue and instead uses queue.h from Ben Noordhuis. This drove most of the, minor, changes in UV. But most of the files are unchanged.
deps/v8 Mostly unchanged with the exception of a few insertions to deal with JXCore’s multi-threading abilities.
deps/Zlib A few minor changes but nothing major.
doc The majority of the files are unchanged other than what appears to be a global search/replace for /node.js/jxcore. A few files are edited where JXCore adds new capabilities.
lib These files look like they are from v0.10.36. The majority of changes are just white space/formatting. I sampled a bunch of the files and what changes there were seemed very minor.
node This is created by JXCore and is where they moved AUTHORS and ChangeLog files from Node.js.
samples This is JXCore code, not node.js code.
src See below
test My main issue is that the tests look like they are from v0.10.26 and I would have preferred they be from v0.10.36. But in any case the tests are there and most files are either not changed or have very mechanical changes like converting NODE_SET_METHOD to JS_METHOD_SET and such. I have to admit that at some point I stopped individually checking all the changed files and just spot checked them because there are literally hundreds of them. But in general the changes were really minor and RI’ing should be pretty easy. Also note that JXCore has added literally 100s of additional test files above and beyond Node.js’s to cover their functionality. Happiness is a large test base.
tools The majority of files are unchanged, what few changes there are, are tiny.
The src directory is by far the part of the code with the most changes from Node.js and that makes a lot of sense because this is the code that primarily handles the relationship between Node.js and v8, not to mention threading. These are the things that JXCore has changed the most.
It’s also worth pointing out that JXCore uses a slightly different file layout than node.js 0.10.36 uses. Specifically a ton of *wrap.* files which live in /src in Node.js are placed in the wrappers sub-directory in JXCore. Similarly the node_win32_* files were moved to src/platform/win and v8_typed_array* and v8abbr.h ended up in JX/Proxy/V8.
In terms of the files I’d least like to own RI’ing my choices would be node.cc, node.js, node_counters.cc/.h, and node_dtrace.cc/.h.
But the bottom line is that even with the heavy surgery performed on the previously listed files I could still see someone with a deep understanding of the macro layer being able to do the RI. The majority of the changes are fairly mechanical. In many cases the JXCore folks choose macro names that mirror the v8 specific names and so make it easier to understand what needs to be changed. I’m not saying that an RI from mainline Node.js would be easy or fun, but it does appear doable.
11 What about RI’ing from Node 0.12.x?
According to the Nubisa folks JXCore was originally written against 0.11.x. So all the big v8 changes in 0.12.x are actually already supported by JXCore. Later on Nubisa decided to move JXCore back to 0.10.x because that is where their customers were. Nevertheless, the hooks for the major changes in 0.12.x are still there. So it should be possible to move to 0.12.x.