diff --git a/pdlua.c b/pdlua.c
index d47a91dce4197567265bbf21157780bd1b84ea50..0b126da670d9b6f315bbebdff152aaa9d4a658e5 100644
--- a/pdlua.c
+++ b/pdlua.c
@@ -512,6 +512,10 @@ static void pdlua_stack_dump (lua_State *L)
     printf("\n");  /* end the listing */
 }
 
+/* nw.js support. If this is non-NULL then we're running inside Jonathan
+   Wilkes' Pd-L2Ork variant and access to the GUI uses JavaScript. */
+static void (*nw_gui_vmess)(const char *sel, char *fmt, ...) = NULL;
+
 /** a handler for the open item in the right-click menu (mrpeach 20111025) */
 /** Here we find the lua code for the object and open it in an editor */
 static void pdlua_menu_open(t_pdlua *o)
@@ -563,7 +567,10 @@ static void pdlua_menu_open(t_pdlua *o)
 #else
         logpost(NULL, 3, "Opening %s for editing", pathname);
 #endif
-        sys_vgui("::pd_menucommands::menu_openfile {%s}\n", pathname);
+        if (nw_gui_vmess)
+          nw_gui_vmess("open_textfile", "s", pathname);
+        else
+          sys_vgui("::pd_menucommands::menu_openfile {%s}\n", pathname);
     }
     PDLUA_DEBUG("pdlua_menu_open end. stack top is %d", lua_gettop(L));
 }
@@ -1608,6 +1615,15 @@ static int pdlua_loader_pathwise
 }
 
 
+#ifndef WIN32
+#define __USE_GNU // to get RTLD_DEFAULT
+#include <dlfcn.h> // for dlsym
+#ifndef RTLD_DEFAULT
+/* If RTLD_DEFAULT still isn't defined then just passing NULL will hopefully
+   do the trick. */
+#define RTLD_DEFAULT NULL
+#endif
+#endif
 
 /** Start the Lua runtime and register our loader hook. */
 #ifdef _WIN32
@@ -1716,6 +1732,13 @@ void pdlua_setup(void)
         error("lua: loader will not be registered!");
     }
     PDLUA_DEBUG("pdlua_setup: end. stack top %d", lua_gettop(L));
+#ifndef WIN32
+    /* nw.js support (currently only supported on Linux and Mac). XXXTODO:
+       Make this work on Windows as well. */
+    nw_gui_vmess = dlsym(RTLD_DEFAULT, "gui_vmess");
+    if (nw_gui_vmess)
+      post("pdlua: using JavaScript interface (Pd-l2ork nw.js version)");
+#endif
 
 }