# Wiki Discussion: SWI-Prolog in the browser using WASM

**URL:** <https://swi-prolog.discourse.group/t/wiki-discussion-swi-prolog-in-the-browser-using-wasm/5651>\
**Category:** Wiki Discussion\
**Created:** [August 3, 2022, 8:21pm UTC](https://swi-prolog.discourse.group/t/wiki-discussion-swi-prolog-in-the-browser-using-wasm/5651 "2022-08-03T20:21:56Z")\
**Posts on this page:** 20\
**Page:** 3

<div class="post-metadata">

**Author:** ![rla](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/rla/32/6863_2.png) [@rla](https://swi-prolog.discourse.group/u/rla)\
**Post date:** [August 9, 2022, 3:52pm UTC](https://swi-prolog.discourse.group/t/wiki-discussion-swi-prolog-in-the-browser-using-wasm/5651/64 "2022-08-09T15:52:53Z")

</div>

> [@jan](#):
>
> One issue is how to call JavaScript from Prolog, so we can manipulate the DOM. I see:
> 
> - emscripten\_run\_script() can call anything, but we get no return value and I’m unsure we can handle exceptions.
> - `EM_JS()` allows calling a fixed JavaScript function. Possibly we can make this work by first placing the function (name) and arguments somewhere, use this and fetch the results from some other well known place?
> - We could use js\_yield(Request, Response)

There is also addFunction which gives a raw function pointer. This allows to register a JavaScript function, obtain a pointer, pass this pointer to WebAssembly and have WebAssembly/C call it as a function. While this is also likely too low level, it’s very likely an important building block to provide a working interface. [Interacting with code — Emscripten 3.1.49-git (dev) documentation](https://emscripten.org/docs/porting/connecting_cpp_and_javascript/Interacting-with-code.html#interacting-with-code-call-function-pointers-from-c)

I dislike emscripten\_run\_script because it leads to code passed around as strings which is incredibly unreadable.

js\_yield is interesting but needs some way to pass around more structured data.

---

<div class="post-metadata">

**Author:** ![jan](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/jan/32/4_2.png) [@jan](https://swi-prolog.discourse.group/u/jan)\
**Post date:** [August 9, 2022, 4:04pm UTC](https://swi-prolog.discourse.group/t/wiki-discussion-swi-prolog-in-the-browser-using-wasm/5651/65 "2022-08-09T16:04:31Z")

</div>

> [@rla](#):
>
> I think so far we built both variants.

As is, we probably need that. The Node version is used for the Prolog built steps (rather than using native Prolog using the _NATIVE\_FRIEND_ mechanism) and is useful for running `ctest`. I guess eventually we want to make this available as an `npm` module where we might only include the browser version?

> [@rla](#):
>
> There is also addFunction which gives a raw function pointer.

I had seen that, but forgot about it ☹ That looks better 🙂 With some auto-generated wrappers we should be able to just call a JavaScript function from Prolog.

---

<div class="post-metadata">

**Author:** ![rla](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/rla/32/6863_2.png) [@rla](https://swi-prolog.discourse.group/u/rla)\
**Post date:** [August 9, 2022, 4:07pm UTC](https://swi-prolog.discourse.group/t/wiki-discussion-swi-prolog-in-the-browser-using-wasm/5651/66 "2022-08-09T16:07:18Z")

</div>

> [@anon95304481](#):
>
> If you completely asyncify your Prolog system integration with the browser,  
> things will look completely differently. At the moment the SWIPL WASM provides  
> some callback hell. This is useful for example to provide the buttons next and  
> abort, by some inverted programming style.

It’s difficult to understand what “complete asyncify” means in this case. It does not seem to be asyncify as meant by Emscripten? [Asynchronous Code — Emscripten 4.0.15-git (dev) documentation](https://emscripten.org/docs/porting/asyncify.html)

From what I understand, Emscripten asyncify comes with heavy overhead in both code size and runtime performance.

I would not say that js\_yield is a callback hell. Many apps just calling Prolog predicates would likely never have to deal with it and calling js\_yield from Prolog itself appears completely sync, there is no need to wrap it in an engine or use Prolog callbacks.

---

<div class="post-metadata">

**Author:** ![EricGT](https://avatars.discourse-cdn.com/v4/letter/e/f1d935/32.png) [@EricGT](https://swi-prolog.discourse.group/u/EricGT)\
**Post date:** [August 9, 2022, 4:15pm UTC](https://swi-prolog.discourse.group/t/wiki-discussion-swi-prolog-in-the-browser-using-wasm/5651/67 "2022-08-09T16:15:12Z")

</div>

@Jan  
@jamesnvc

FYI

One feature this Discourse site is lacking is the ability to run code in place in a post.

This might be possible now that the SWI-Prolog WASM (#wasm\_wiki #wasm\_demo) is making progress.

As we (Discourse admins) know we can not add anything we want to this Discourse site but we can add [theme components](https://meta.discourse.org/t/beginners-guide-to-using-discourse-themes/91966) as we did with

> **[GitHub - jamesnvc/discourse-linkify-prolog-predicates: theme to auto linkify...](https://github.com/jamesnvc/discourse-linkify-prolog-predicates)**
>
> theme to auto linkify urls in discourse. Contribute to jamesnvc/discourse-linkify-prolog-predicates development by creating an account on GitHub.

Based on

> **[Discourse theme components now support Wasm 🎊](https://meta.discourse.org/t/discourse-theme-components-now-support-wasm/223574)**
>
> WebAssembly (Wasm) is a technology that ships in all modern browsers that lets developers ship portable binary programs. This means that developers can use almost any programming language and target the web. In the context of Discourse this opens...

all of the stars seem to be aligning for this to happen.

---

<div class="post-metadata">

**Author:** ![rla](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/rla/32/6863_2.png) [@rla](https://swi-prolog.discourse.group/u/rla)\
**Post date:** [August 9, 2022, 4:20pm UTC](https://swi-prolog.discourse.group/t/wiki-discussion-swi-prolog-in-the-browser-using-wasm/5651/69 "2022-08-09T16:20:46Z")

</div>

> [@jan](#):
>
> The WASM version clearly wants the HTML, JavaScript and JSON support, but not the HTTP server libraries.

How feasible it would be extracting JSON-related code from there? HTML is big one and probably troublesome since so many guides and documentation refers to HTML support as being from http package.

General JSON representation was mentioned here:

> [@Blocking operations in the WASM version (JavaScript expertise needed)](https://swi-prolog.discourse.group/t/blocking-operations-in-the-wasm-version-javascript-expertise-needed/5655/16):
>
> Sounds good. For now my emphasis is on the low level. I definitely need support to get the high level right. I have had discussions with @ericzinda on a new general JSON representation for Prolog terms. The idea is to create something where the terms you normally like to transfer (lists, strings, numbers, objects) come pretty natural, but the representation has escapes that allow for faithful round trip of arbitrary Prolog terms. One thing at a time slight_smile Auto yield is in the…

Was it about this representation? [https://www.swi-prolog.org/pldoc/doc\_for?object=term\_to\_json/3](https://www.swi-prolog.org/pldoc/doc_for?object=term_to_json/3)

---

<div class="post-metadata">

**Author:** ![rla](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/rla/32/6863_2.png) [@rla](https://swi-prolog.discourse.group/u/rla)\
**Post date:** [August 9, 2022, 4:31pm UTC](https://swi-prolog.discourse.group/t/wiki-discussion-swi-prolog-in-the-browser-using-wasm/5651/70 "2022-08-09T16:31:43Z")

</div>

> [@jan](#):
>
> I guess eventually we want to make this available as an `npm` module where we might only include the browser version?

I think ideally it should be both and on Node.js you should be able to select either of them. The actual WebAssembly binary should be exactly the same. The difference is in the wrapping JavaScript provided by Emscripten. I’m working slowly on the package. My main goal so far was actually TypeScript support and automated build through docker to make current code easier to use by others. Improving API, term representation etc. was secondary.

---

<div class="post-metadata">

**Author:** ![peter.ludemann](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/peter.ludemann/32/48_2.png) [@peter.ludemann](https://swi-prolog.discourse.group/u/peter.ludemann)\
**Post date:** [August 9, 2022, 8:13pm UTC](https://swi-prolog.discourse.group/t/wiki-discussion-swi-prolog-in-the-browser-using-wasm/5651/73 "2022-08-09T20:13:40Z")

</div>

Besides Javascript/Typescript, there’s also Dart (used to implement Flutter, I think), which runs in the browser (Chrome, Edge, Firefox, Safari). Some years ago, I attended a talk that claimed Dart had more parallelism than Javascript, but I don’t remember the details; and Javascript might have adopted some or all of Dart’s parallelism features in the interim.

Anyway, I found a few articles, in case they’re useful:

> **[Dart asynchronous programming: Isolates and event loops](https://medium.com/dartlang/dart-asynchronous-programming-isolates-and-event-loops-bffc3e296a6a)**
>
> Dart, despite being a single-threaded language, offers support for futures, streams, background work, and all the other things you need to…

> **[Concurrency in Dart](https://dart.dev/guides/language/concurrency)**
>
> Use isolates to enable parallel code execution on multiple processor cores.

---

<div class="post-metadata">

**Author:** ![jan](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/jan/32/4_2.png) [@jan](https://swi-prolog.discourse.group/u/jan)\
**Post date:** [August 10, 2022, 8:03am UTC](https://swi-prolog.discourse.group/t/wiki-discussion-swi-prolog-in-the-browser-using-wasm/5651/75 "2022-08-10T08:03:10Z")

</div>

> [@rla](#):
>
> Was it about this representation? [term\_to\_json/3](https://www.swi-prolog.org/pldoc/doc_for?object=term_to_json/3)

That was the starting point. I have been discussing a new JSON format with @ericzinda at [Consider adding an option to use a different JSON Format · Issue #4 · SWI-Prolog/packages-mqi · GitHub](https://github.com/SWI-Prolog/packages-mqi/issues/4)

> [@rla](#):
>
> How feasible it would be extracting JSON-related code from there? HTML is big one and probably troublesome since so many guides and documentation refers to HTML support as being from http package.

It is not very hard of course. The main issue is what you hint at: a lot of stuff will move and that has implications for the build process, users and documentation. We can minimize some of that by adding a library at the old location that loads and reexports the new library (and prints a deprecated warning). That is also what happened to the DCG support that started in the HTTP package as well. I’m still in doubt. The other option would be to simply minimize the HTTP package for the WASM version. That is far easier but doesn’t solve the long term issue.

One of the next steps is to be able to add the foreign libraries in the WASM version.

---

<div class="post-metadata">

**Author:** ![jan](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/jan/32/4_2.png) [@jan](https://swi-prolog.discourse.group/u/jan)\
**Post date:** [August 11, 2022, 3:30pm UTC](https://swi-prolog.discourse.group/t/wiki-discussion-swi-prolog-in-the-browser-using-wasm/5651/76 "2022-08-11T15:30:25Z")

</div>

> [@jan](#):
>
> > [@rla](#):
> >
> > Was it about this representation? [term\_to\_json/3](https://www.swi-prolog.org/pldoc/doc_for?object=term_to_json/3)
> 
> That was the starting point. I have been discussing a new JSON format with @ericzinda at [Consider adding an option to use a different JSON Format · Issue #4 · SWI-Prolog/packages-mqi · GitHub](https://github.com/SWI-Prolog/packages-mqi/issues/4)

I have now added support for @ericzinda’s proposal for JSON/Object representation to the `prolog.js` module as Prolog.toJSON() and Prolog.toProlog() that is connected to the WASM version. I’m also working towards a better high level interface to call Prolog from JavaScript. You can see it at work at [https://dev.swi-prolog.org/wasm/test](https://dev.swi-prolog.org/wasm/test). The source is in the `src/wasm` directory as `test.html` and `test.pl`. Roughly, this adds:

- A `Prolog.consult(url1, url2, ...).then(function)` that downloads the urls from the server, puts them in `/tmp` and loads them into Prolog.
- `Prolog.query(...)` which has several signatures and returns an _iterable_ object that represents the query. So, we can do call a goal from a string and get the bindings as an object that holds the JavaScript translation of the results, using the variables as keys. Variables starting with an `_` are not included in this object.

```prolog
  Prolog.with_frame(() =>
  { let n = 0;

    for(const r of Prolog.query("p(X)"))
    { println("stdout", r.X);
    }
  });

```

Or, provide input and do a _once_ goal. The code below computes the sum of all numbers in a list in Prolog. It takes an object with _input_ bindings that is translated to Prolog data. The output object does **not** include the input variables.

```prolog
function sum_list(list)
{ return Prolog.with_frame(() =>
  { return Prolog.query("sum_list(List, Sum)", {List:list}).once().Sum;
  });
}

```

There are still several issues with this stuff.

- I’d rather get rid of the `Prolog.with_frame()` that scopes the Prolog terms references.
- Breaking out of the query due to an exception (not yet done) or a break from the for…of construct does not close it. AFAIK JavaScript has no destructor like C++ when an object gets out of scope.
- Errors are practically nowhere handled. I’m still doubting between return codes and JavaScript exceptions. The lack of destructors might make cleanup complicated ☹
- It all looks pretty ugly and is not documented.

Still, feedback on the overall direction is welcome 🙂

---

<div class="post-metadata">

**Author:** ![rla](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/rla/32/6863_2.png) [@rla](https://swi-prolog.discourse.group/u/rla)\
**Post date:** [August 11, 2022, 5:43pm UTC](https://swi-prolog.discourse.group/t/wiki-discussion-swi-prolog-in-the-browser-using-wasm/5651/77 "2022-08-11T17:43:29Z")

</div>

> [@jan](#):
>
> - I’d rather get rid of the `Prolog.with_frame()` that scopes the Prolog terms references.
> - Breaking out of the query due to an exception (not yet done) or a break from the for…of construct does not close it. AFAIK JavaScript has no destructor like C++ when an object gets out of scope.
> - Errors are practically nowhere handled. I’m still doubting between return codes and JavaScript exceptions. The lack of destructors might make cleanup complicated ☹
> - It all looks pretty ugly and is not documented.

In my opinion it looks pretty good. It is much more usable than it was a week ago. We could just require query to be closed and throw an error if a new query is opened without closing the previous one (another option is to queue them).

Your JavaScript is very good and pretty much self-documenting. Only the indentation is a bit odd but it matches the C code style in SWI 🙂

I would like to provide Typescript annotations. For JavaScript programmers they would be very helpful since modern IDE-s will display and autocomplete code by them. Things are moving very fast but I hope to find time to put into this.

---

<div class="post-metadata">

**Author:** ![jan](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/jan/32/4_2.png) [@jan](https://swi-prolog.discourse.group/u/jan)\
**Post date:** [August 18, 2022, 2:13pm UTC](https://swi-prolog.discourse.group/t/wiki-discussion-swi-prolog-in-the-browser-using-wasm/5651/79 "2022-08-18T14:13:41Z")

</div>

I have pushed an update to #wasm and updated the [wiki page](https://swi-prolog.discourse.group/t/swi-prolog-in-the-browser-using-wasm/5650). There are two big developments:

- Call between Prolog and JavaScript and JavaScript and Prolog are getting close to their final version.
- Calls from Prolog to JavaScript can represent DOM elements as Prolog _blobs_. The DOM elements known to Prolog are subject to Prolog garbage collection 🙂

For example, we can how define a Prolog predicate to add a paragraph to the _shell_ output window:

```prolog
add_par(Text) :-
  Out := document.getElementById("output"),
  More := document.getElementById("more"),
  Par := document.createElement("p"),
  Par.textContent := Text,
  _ := Out.insertBefore(Par, More).

```

After which we can call

```
?- add_par("Hello world!").

```

We can also call the other way around nicely, for example writing all the results of `p/1`:

```javascript
for(const r of Prolog.query("p(X)")) {
  console.log(r.X);
}

```

---

<div class="post-metadata">

**Author:** ![jan](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/jan/32/4_2.png) [@jan](https://swi-prolog.discourse.group/u/jan)\
**Post date:** [August 18, 2022, 2:39pm UTC](https://swi-prolog.discourse.group/t/wiki-discussion-swi-prolog-in-the-browser-using-wasm/5651/81 "2022-08-18T14:39:17Z")

</div>

It is indeed inspired by @nicos work on R/real. I don’t know whether this approach has a name. This can’t deal with functions and other complex syntax. We notably need a way to add event listeners.

> [@anon95304481](#):
>
> So basically you would write  
> **add\_par()** in JavaScript and register it to Prolog.

There is no need to register anything. Just define the function and call `_ := add_par("Hello world!")` Of course you can define a wrapper predicate or we can add something that creates these wrappers.

---

<div class="post-metadata">

**Author:** ![josderoo](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/josderoo/32/3752_2.png) [@josderoo](https://swi-prolog.discourse.group/u/josderoo)\
**Post date:** [August 18, 2022, 7:53pm UTC](https://swi-prolog.discourse.group/t/wiki-discussion-swi-prolog-in-the-browser-using-wasm/5651/83 "2022-08-18T19:53:51Z")

</div>

Aside from the above, in EYE we have to do

```prolog
:- catch(use_module(library(sha)), _, true).
:- catch(use_module(library(pcre)), _, true).
:- catch(use_module(library(http/http_open)), _, true).
:- catch(use_module(library(semweb/rdf_turtle)), _, true).

```

because those libraries are not yet available in WASM.  
This is not a burning issue, I just wondered if there is a plan to support those libraries in WASM?

---

<div class="post-metadata">

**Author:** ![jan](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/jan/32/4_2.png) [@jan](https://swi-prolog.discourse.group/u/jan)\
**Post date:** [August 19, 2022, 7:18am UTC](https://swi-prolog.discourse.group/t/wiki-discussion-swi-prolog-in-the-browser-using-wasm/5651/85 "2022-08-19T07:18:11Z")

</div>

> [@anon95304481](#):
>
> The result is, so one is free to do whatever one wants with `(:=)/2`?!

Yes. What is wrong with that? You can do whatever JavaScript can do except for stuff that requires more complex syntax such as functions. In other words you can access methods, setters and getters and chain these using a.b.c… In fact, internally they are chained as a[b][c]… because . is a function in SWI-Prolog. goal\_expansion on a.b.c… translates this to a[b][c]… to avoid the function evaluation. Next step :=/2 translates this into a Prolog term that expresses the actions that need to be done as a list of primitive actions. This is passed through ‘$js\_call’/2 which is defined using EM\_ASM\_INT(), passing the raw Prolog terms to JavaScript. JavaScript calls Prolog.toJSON() (should that be Prolog.toObject()? as it is not really JSON). JavaScript executes the (now) array of actions resulting in a return value. This is handed to Prolog.toProlog() and made available as the result. If the arguments are sufficiently instantiated we could do most of the translation at compile time and simply pass the shared JavaScript object.

> [@josderoo](#):
>
> because those libraries are not yet available in WASM.  
> This is not a burning issue, I just wondered if there is a plan to support those libraries in WASM?

Most of them depend on foreign components. I have not yet looked into how easy or hard it is to support these. It seems emscripten has a notion of shared libraries, so it should be possible. Opening a URL as a stream as done by library(http/http\_open) may be a real problem. A quick search suggests that emscripten has sockets, but they are a wrapper around websockets, not raw TCP/IP sockets. The obvious solution is to download in JavaScript, similar to Prolog.consult().then(), which downloads a file asynchronously using fetch(), compiles the file and runs the then(). This would not allow _streaming_ parsing of e.g. Turtle input.

---

<div class="post-metadata">

**Author:** ![jan](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/jan/32/4_2.png) [@jan](https://swi-prolog.discourse.group/u/jan)\
**Post date:** [August 19, 2022, 11:12am UTC](https://swi-prolog.discourse.group/t/wiki-discussion-swi-prolog-in-the-browser-using-wasm/5651/88 "2022-08-19T11:12:07Z")

</div>

> [@anon95304481](#):
>
> Wasn’t [SWISH](https://swish.swi-prolog.org/) a client sandbox? Or mainly a server sandbox?

SWISH is just a server side sandbox. And yes, doing eval() on strings is dangerous if you do not control where the string comes from. Otherwise I don’t see the difference with `<script>` elements.

---

<div class="post-metadata">

**Author:** ![jan](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/jan/32/4_2.png) [@jan](https://swi-prolog.discourse.group/u/jan)\
**Post date:** [August 19, 2022, 3:35pm UTC](https://swi-prolog.discourse.group/t/wiki-discussion-swi-prolog-in-the-browser-using-wasm/5651/91 "2022-08-19T15:35:23Z")

</div>

> [@josderoo](#):
>
> ```prolog
> :- catch(use_module(library(sha)), _, true).
> :- catch(use_module(library(pcre)), _, true).
> :- catch(use_module(library(http/http_open)), _, true).
> :- catch(use_module(library(semweb/rdf_turtle)), _, true).
> 
> ```

I pushed a starting point to deal with this. After reading all the warning on emscripten against using dynamic linking I decided for another route I had in mind to resolve this issue: allow adding the foreign extensions to the core system. This is now a new option `-DSTATIC_EXTENSIONS` to `cmake` which is enabled by default for Emscripten. This allows building fully static SWI-Prolog executables with extensions, which surely has value on its own 🙂

Currently includes some of the `clib` libraries, the `sgml` library and some of the `http` libraries.

An overall worry is the size of the whole thing ☹

Pushed to #wasm\_demo

---

<div class="post-metadata">

**Author:** ![josderoo](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/josderoo/32/3752_2.png) [@josderoo](https://swi-prolog.discourse.group/u/josderoo)\
**Post date:** [August 19, 2022, 7:49pm UTC](https://swi-prolog.discourse.group/t/wiki-discussion-swi-prolog-in-the-browser-using-wasm/5651/92 "2022-08-19T19:49:27Z")

</div>

> [@josderoo](#):
>
> `use_module(library(sha))`

now works fine, thanks @jan

---

<div class="post-metadata">

**Author:** ![josderoo](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/josderoo/32/3752_2.png) [@josderoo](https://swi-prolog.discourse.group/u/josderoo)\
**Post date:** [August 20, 2022, 8:58pm UTC](https://swi-prolog.discourse.group/t/wiki-discussion-swi-prolog-in-the-browser-using-wasm/5651/93 "2022-08-20T20:58:57Z")

</div>

After seeing

```prolog
commit 7d8f1e2eba12b0d245ac92ca7a5547f1c6f0589a
Author: Jan Wielemaker <J.Wielemaker@vu.nl>
Date: Sat Aug 20 10:09:42 2022 +0200

    Included turtle and ntriple libraries in WASM build.

```

we tested the latest version but get

```prolog
ERROR: source_sink `library(semweb/rdf_turtle)' does not exist

```

---

<div class="post-metadata">

**Author:** ![jan](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/jan/32/4_2.png) [@jan](https://swi-prolog.discourse.group/u/jan)\
**Post date:** [August 21, 2022, 7:05am UTC](https://swi-prolog.discourse.group/t/wiki-discussion-swi-prolog-in-the-browser-using-wasm/5651/96 "2022-08-21T07:05:22Z")

</div>

> [@josderoo](#):
>
> ```prolog
> ERROR: source_sink `library(semweb/rdf_turtle)' does not exist
> 
> ```

I didn’t include this deprecated library. It just loads `library(semweb/turtle)'. Note that the writing part of this library does not yet work as it depends on semweb/rdf\_db and the C part of the RDF store heavily depends on threading.

---

<div class="post-metadata">

**Author:** ![josderoo](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/josderoo/32/3752_2.png) [@josderoo](https://swi-prolog.discourse.group/u/josderoo)\
**Post date:** [August 21, 2022, 11:16am UTC](https://swi-prolog.discourse.group/t/wiki-discussion-swi-prolog-in-the-browser-using-wasm/5651/97 "2022-08-21T11:16:59Z")

</div>

> [@jan](#):
>
> I didn’t include this deprecated library. It just loads `library(semweb/turtle)'.

Aha, that is nice and I will use `library(semweb/turtle)` from now on. Thanks!

[Previous page](https://swi-prolog.discourse.group/t/wiki-discussion-swi-prolog-in-the-browser-using-wasm/5651.md?page=2)

[Next page](https://swi-prolog.discourse.group/t/wiki-discussion-swi-prolog-in-the-browser-using-wasm/5651.md?page=4)
