Go vs JavaScript runtime

Is there any information regarding Go vs JavaScript runtime performance?

Initially, I wanted to work in JavaScript as I already have experience with it, and never tried Go. However, due to the limitations of the JS VM (many of the NPM packages I’m familiar with might not be compatible), I’m considering Go.

Looking at the Go runtime documentation, it’s said that the full range of packages are compatible, so I won’t have to worry about incompatible packages like with JavaScript runtime. I’m wondering if Go will provide a better developer experience and is worth learning to use instead of JavaScript?

Hello @KamilDev,

This is a bit subjective, as the developer experience can vary depending on your experience with a given language.

I’d say that if you’re looking for raw performance, Go is the way to go. As you mention, there’s also less restrictions on the module ecosystem given that it doesn’t have the restrictions of Nakama’s JS environment being ES5 and incompatible with Node specific packages.

There are also some caveats to consider though, the Go runtime requires the plugin module to be built every time the code is changed, so code-reloading isn’t as fast, the environment is not fully sandboxed, and dependency pinning may be needed if you import modules that Nakama uses itself.

My personal (biased) opinion is that Go is quite straightforward and is worth trying out - you can have a look at our project template to see how the code would differ between both implementations.

My advice would be to try to implement a couple of RPCs in Go and others in JS and see how you fare and make up your mind on which you prefer - remember that you can have different functionality implemented in both runtimes.

Best.

I couldn’t really find any information regarding TypeScript code-reloading or hot-reloading. Is it correct that we must always run docker compose up --build nakama after making changes?

I use something like this package.json to automatically watch for changes, not sure if there’s any better or faster approach:

 "scripts": {
    "build": "rollup -c",
    "type-check": "tsc --noEmit",
    "start": "docker compose up --build nakama",
    "watch": "nodemon --watch src --ext ts --delay 1 --exec \"npm run build && npm run start\"",
    "dev": "npm run watch"
  },

Nakama doesn’t support code-reloading natively, so the server has to be restarted, which is easily achievable with some script such as the one you provided, but it’ll depend on the build tooling used by the developer, so we don’t provide recommendations on how to achieve it, but I believe there’s suggestions around the forum.

I think that you can optimize further by using Docker volumes, build the code locally and then have the container restart and reload it without having to rebuild the whole container, but I don’t have a solution at hand so you’ll have to experiment.

I’d like to provide feedback that you should consider adding such examples somewhere in the documentation for those interested. I have no particular tooling preferences in mind when picking up Nakama, I would use whatever is recommended and documented.

As this person said:

As with all things, docs need to be maintained, and it’s not trivial to keep everything up to date and working, especially since our docs are becoming quite extensive and given that the JS ecosystem tooling changes so often - we’re constantly working to improve our processes. Please also keep in mind we’re a small team.

I disagree with the post saying this is has to be solved in the application - while I see the convenience this would bring during development, there’s reasons why we’ve been refraining from doing so, one being that there’s alternatives that can work quite well, among others.

So I’ll flip this around, and say that if you find a more optimal workflow to continuously reload your transpiled JS code in Nakama, please do not refrain from sharing it with the community here, someone else may benefit as well.

Looking in the forum, I only found a similar solution to which I currently use. The only other thing I found was this GitHub repository from 4 years ago:

Based on the gif, it looks like it’s very fast restarting. I will have to read up on how this works to see if I can implement into my Nakama project.

I understand maintaining docs is difficult, but I do hope you add an example to the TypeScript Runtime documentation about code-reloading if your resources ever allow. I truly expected there was going to be a section in there about auto code-reloading, but alas nothing.

Regarding the issue of JS tooling documentation constantly needing to be updated, I would still rather an outdated example so I have a better idea where to look, rather then nothing at all.

Lastly, the documentation pages should really contain a “Last updated: date” at the bottom of the page. This is present in nearly all other documentation sites, but I cannot find it in Nakama docs, unless I’m looking in the wrong spot. This will allow the reader to make a better educated guess if an issue encountered could be due to an outdated tutorial.

Hi, thanks for your suggestion. Is this what you had in mind:
package.json

"scripts": {
    "build": "rollup -c",
    "type-check": "tsc --noEmit",
    "start": "docker compose up nakama",
    "start:fresh": "docker compose up --build nakama",
    "watch": "nodemon --watch src --ext ts --delay 1 --exec \"npm run build && docker compose restart nakama\"",
    "dev": "concurrently \"npm run watch\" \"npm run start\""
  },

docker-compose.yml

+  volumes:
+      - ./build:/nakama/data/modules/build

I tested out adding/removing RPCs, and it appears to correctly reflect the changes in Nakama Console.

Please let me know if I implemented it correctly and in the best manner.

Hello @KamilDev,

Yes that’s what I was thinking, if the changes are reflecting correctly between builds then I think you’re good to go.

Best.

1 Like