So, as a few of my posts here have hinted at so far, I’ve been experimenting with other languages on Glitch, seeing what I could get working just with what’s installed on the container. I’ve especially been focusing on compile-to-JS languages that are available on NPM because of the space savings from pnpm and caching.
I thought it might be helpful to keep a list of what I’ve discovered so far. Moderator @cassey has also created a Glitch collection of non-JS projects you can remix, including many of the ones mentioned here. Feel free to comment with your own experiments.
Native languages:
- Java: OpenJDK 1.8 and Maven are present. Otherwise untested.
-
.NET: .NET Core 2.1 is installed including the
dotnet
CLI tool along with the ASP.NET runtimes. I was able to compile a basic F# HelloWorld using this guide. See also Fable below. - Python: both Python 2.7 and 3.5 are installed as well as pip. There is a hello world starter glitch for Python/Flask available for remix.
- Go: A template exists for a Go app using the gin framework.
-
Rust: Works. I was able to build a hello-rust template using the Iron framework for the backend. Note that due to disk space premium, some of the more popular options like
actix-web
andnickel
were a no go: they run out of disk space during compilation. (UPDATE: At the moment, it appears Cargo is not working anymore, see thread: How do I install packages with Rust?) -
Racket: Works by installing the minimal Racket distribution locally. Two sample apps are available, a very basic REST API with Spin, and a more extensive server-side rendered sample app. Use
.scm
extensions instead of.rkt
if you want syntax highlighting in the editor. -
Other langs found in
ls -al /usr/bin
but untested:- C/C++. Both gcc and clang. Also LLVM tools.
- Haskell.
ghc
,haddock
, andcabal
are installed. - OCaml. the OCaml compiler and camlp4 are installed.
- Perl. including CPAN.
- Erlang.
- Elixir.
- Lua 5.2.
- PHP and/or PHP7.
- Ruby, including Rails
- Swift
Compile to JS languages:
- Typescript: Installs via npm. Not tested personally, but unsurprisingly seems to work just fine as there’s a number of projects using it, including several “hello world” type starter apps to remix.
- Elm: Installs via npm, works great. Have written several little projects, including a hello world to start with. Slight gotcha here: for some reason the “add dependency” tool finds some very ancient version of Elm labeled “2.0.0” rather than the actual current version of 0.19, so it’s best to manually install this.
- ClojureScript: Can install the lumo-cljs compiler via npm, and basic compilation works, as well as backend node dependencies. However a bug in the CLJS compiler seems to break library imports for frontend applications due to how it handles symlinks. I’ve talked this over with Lumo’s dev and a fix may come, but he’s quite busy with other projects at the moment.
- Fable: F# to JS compiler. Works! I’ve built a project from the minimal Fable template here. Note that the deps do eat quite a bit of disk space.
- Bucklescript: OCaml to JS compiler, also used for Facebook’s Reason. Works, but you must install via the GUI “add package” tool in the editor. If you install manually at the console it will “lose” the built bsb compiler on the next restart. Also the initial install takes a very long time as it has to build the compiler from source, but restart time seems to be fine after that. I’ve created a hello-world demo.
-
Purescript: You can install the Purescript tools if you first run
enable-npm
in the console. I’ve created a very simple hello-purescript for using PS with Bower.psc-package
seems to fail on installing packages, so can’t recommend that.
The Glitch "lifecycle"
If you start from the node-app/hello-express
project template, Glitch will run the project with pnpm install --shamefully-flatten && npm start
, and the sample code hosts the static index.html
via Express through a random forwarded port. Changes to Javascript and HTML files will automatically trigger a rerun of npm start
, while changes to the package.json
will also rerun pnpm install
.
This is useful for compile-to-JS languages, as you can just customize the start
script to compile your language of choice, and then have the index.html
point to your build output for the JS.
However, as it won’t necessarily know to reload on file changes to non-JS files, you’ll need to customize the file watcher, which you can do by creating a watch.json
file, with the same contents as the "watch"
key described in glitch.json
below.
glitch.json
For non-JS projects, you can instead create a glitch.json
file to tell Glitch how to setup and run your projects. This should contain the following keys:
-
"install"
- this key indicates the command to run when first setting up the environment. It’s best to put here stuff that won’t change every time you change your code, like initial tool/dependency install and setup. -
"start"
- this key indicates the command to run to start the server. So this should include whatever compilation/execution steps are needed to be done every time the code changes. Note that Glitch expects that after running this command, there will be a web server waiting on an open port; if there’s not it will just keep restarting until it does. -
"watch"
- this key contains the file watcher configuration that tells Glitch on which file changes to reinstall/restart the server. This is technically optional, but without it, Glitch will only automatically restart if you changeglitch.json
file itself.
The "watch"
key itself has three potential keys in it. "install"
and "start"
describe the files to watch and trigger a rerun of the commands in those keys above. Each should each contain an object with "include"
and "exclude"
keys, which contain arrays of strings, each string being a regex pattern matching a possible filename(s). Whenever a file changes that is matched by the include
key, it will rerun the appropriate command (start or install), unless the file also matches one of the patterns in exclude
.
The third, optional, key in "watch"
is "throttle"
, which contain the maximum frequency within which Glitch should restart after changes, given in milliseconds.
For an example of what all this looks like, here’s the glitch.json
from Rantstack:
{
"install": "sh ./install.sh",
"start": "racket/bin/racket rantstack.scm",
"watch": {
"install": {
"include": [
"^glitch\\.json$",
"^install\\.sh$",
"^\\.env$"
]
},
"restart": {
"exclude": [
"^racket/"
],
"include": [
"\\.rkt$",
"\\.scm$"
]
},
"throttle": 1000
}
}
Some other notes from my experimentation:
- Because of the way Glitch “restarts the world”, optimization is kind of a tradeoff here: it may be useful to use optimized output for payload size’s sake or if it improves end-user performance, but as this will also slow down the startup time of the instance, your initial loading time could be much longer.
- The
hello-webpage/webpage
starter template does not havenode
installed, but does have Python, OpenJDK, and .NET Core installed still. - The Python/Flask template instead uses a
start.sh
bash script to start the server. I haven’t experimented with this further, but I suspect usingglitch.json
gives you some more flexibility. - Disk space is very limited. Disk space is only 200MB, so that limits the amount of space we have for dependencies, installing additional tools, etc. npm dependencies are sort of an exception though, as much of that is cached by pnpm and Glitch so that it doesn’t count against the instance size limit. Be careful hitting the limit too, as instances can get “stuck” in a loop when close to the cap.
- RAM is a bit tight. Instance has 512MB of RAM, which is not bad for lightweight servers, but not good for running big toolchains in memory. When writing your build scripts, don’t bother with live reloading tools and the like, since Glitch will restart the whole server on change anyway. Compile once.
- The port that the Glitch proxy will pick up to serve as the web server can be found from the environment variable
PORT
. This usually seems to be 3000, and it will also detect a server running on port 8080 automatically, but it’s probably best practice to use the env var.
I hope this is helpful, and if any of the Glitch folks have further insights on some of the unclear stuff, or you’ve done your own experiments feel free to share. I’ll try and keep this post updated.
Updated: 02-Jun-2019